From 58afa7498e3a7439238e54644c486c7b625e9a1b Mon Sep 17 00:00:00 2001 From: "alonso.torres" Date: Fri, 24 Nov 2023 15:33:59 +0100 Subject: [PATCH 1/6] :recycle: Move card width calculation to hook --- frontend/src/app/main/ui/dashboard/files.cljs | 29 +-------------- .../src/app/main/ui/dashboard/libraries.cljs | 30 +-------------- .../src/app/main/ui/dashboard/projects.cljs | 30 +-------------- .../src/app/main/ui/dashboard/search.cljs | 30 +-------------- frontend/src/app/main/ui/hooks.cljs | 37 +++++++++++++++++++ 5 files changed, 45 insertions(+), 111 deletions(-) diff --git a/frontend/src/app/main/ui/dashboard/files.cljs b/frontend/src/app/main/ui/dashboard/files.cljs index 1ad4e9ada8..d7646d5b6e 100644 --- a/frontend/src/app/main/ui/dashboard/files.cljs +++ b/frontend/src/app/main/ui/dashboard/files.cljs @@ -6,7 +6,6 @@ (ns app.main.ui.dashboard.files (:require - [app.common.math :as mth] [app.main.data.dashboard :as dd] [app.main.data.events :as ev] [app.main.refs :as refs] @@ -14,13 +13,12 @@ [app.main.ui.dashboard.grid :refer [grid]] [app.main.ui.dashboard.inline-edition :refer [inline-edition]] [app.main.ui.dashboard.project-menu :refer [project-menu]] + [app.main.ui.hooks :as hooks] [app.main.ui.icons :as i] [app.util.dom :as dom] [app.util.i18n :as i18n :refer [tr]] [app.util.keyboard :as kbd] [app.util.router :as rt] - [app.util.webapi :as wapi] - [beicon.core :as rx] [cuerdas.core :as str] [rumext.v2 :as mf])) @@ -126,16 +124,8 @@ [{:keys [project team] :as props}] (let [files-map (mf/deref refs/dashboard-files) project-id (:id project) - width (mf/use-state nil) - rowref (mf/use-ref) - itemsize (if (>= @width 1030) - 280 - 230) - ratio (if (some? @width) (/ @width itemsize) 0) - nitems (mth/floor ratio) - limit (min 10 nitems) - limit (max 1 limit) + [rowref limit] (hooks/use-dynamic-grid-item-width) files (mf/with-memo [project-id files-map] (->> (vals files-map) @@ -160,21 +150,6 @@ (st/emit! (-> (dd/create-file (with-meta params mdata)) (with-meta {::ev/origin origin}))))))] - (mf/with-effect [] - (let [node (mf/ref-val rowref) - mnt? (volatile! true) - sub (->> (wapi/observe-resize node) - (rx/observe-on :af) - (rx/subs (fn [entries] - (let [row (first entries) - row-rect (.-contentRect ^js row) - row-width (.-width ^js row-rect)] - (when @mnt? - (reset! width row-width))))))] - (fn [] - (vreset! mnt? false) - (rx/dispose! sub)))) - (mf/with-effect [project] (when project (let [pname (if (:is-default project) diff --git a/frontend/src/app/main/ui/dashboard/libraries.cljs b/frontend/src/app/main/ui/dashboard/libraries.cljs index 84070ad555..fa14becee2 100644 --- a/frontend/src/app/main/ui/dashboard/libraries.cljs +++ b/frontend/src/app/main/ui/dashboard/libraries.cljs @@ -7,16 +7,14 @@ (ns app.main.ui.dashboard.libraries (:require [app.common.data :as d] - [app.common.math :as mth] [app.main.data.dashboard :as dd] [app.main.features :as features] [app.main.refs :as refs] [app.main.store :as st] [app.main.ui.dashboard.grid :refer [grid]] + [app.main.ui.hooks :as hooks] [app.util.dom :as dom] [app.util.i18n :as i18n :refer [tr]] - [app.util.webapi :as wapi] - [beicon.core :as rx] [rumext.v2 :as mf])) (mf/defc libraries-page @@ -35,16 +33,7 @@ components-v2 (features/use-feature "components/v2") - width (mf/use-state nil) - rowref (mf/use-ref) - - itemsize (if components-v2 - 350 - (if (>= @width 1030) 280 230)) - ratio (if (some? @width) (/ @width itemsize) 0) - nitems (mth/floor ratio) - limit (min 10 nitems) - limit (max 1 limit)] + [rowref limit] (hooks/use-dynamic-grid-item-width 350)] (mf/with-effect [team] (when team @@ -57,21 +46,6 @@ (st/emit! (dd/fetch-shared-files) (dd/clear-selected-files))) - (mf/with-effect [] - (let [node (mf/ref-val rowref) - mnt? (volatile! true) - sub (->> (wapi/observe-resize node) - (rx/observe-on :af) - (rx/subs (fn [entries] - (let [row (first entries) - row-rect (.-contentRect ^js row) - row-width (.-width ^js row-rect)] - (when @mnt? - (reset! width row-width))))))] - (fn [] - (vreset! mnt? false) - (rx/dispose! sub)))) - [:* [:header.dashboard-header {:ref rowref} [:div.dashboard-title#dashboard-libraries-title diff --git a/frontend/src/app/main/ui/dashboard/projects.cljs b/frontend/src/app/main/ui/dashboard/projects.cljs index 7ffcad5475..0455c4aaf4 100644 --- a/frontend/src/app/main/ui/dashboard/projects.cljs +++ b/frontend/src/app/main/ui/dashboard/projects.cljs @@ -8,7 +8,6 @@ (:require [app.common.data :as d] [app.common.geom.point :as gpt] - [app.common.math :as mth] [app.config :as cf] [app.main.data.dashboard :as dd] [app.main.data.events :as ev] @@ -20,14 +19,13 @@ [app.main.ui.dashboard.grid :refer [line-grid]] [app.main.ui.dashboard.inline-edition :refer [inline-edition]] [app.main.ui.dashboard.project-menu :refer [project-menu]] + [app.main.ui.hooks :as hooks] [app.main.ui.icons :as i] [app.util.dom :as dom] [app.util.i18n :as i18n :refer [tr]] [app.util.keyboard :as kbd] [app.util.router :as rt] [app.util.time :as dt] - [app.util.webapi :as wapi] - [beicon.core :as rx] [cuerdas.core :as str] [okulary.core :as l] [potok.core :as ptk] @@ -168,16 +166,7 @@ :menu-pos nil :edition? (= (:id project) edit-id)}) - width (mf/use-state nil) - rowref (mf/use-ref) - itemsize (if (>= @width 1030) - 280 - 230) - - ratio (if (some? @width) (/ @width itemsize) 0) - nitems (mth/floor ratio) - limit (min 10 nitems) - limit (max 1 limit) + [rowref limit] (hooks/use-dynamic-grid-item-width) on-nav (mf/use-fn @@ -258,21 +247,6 @@ (dd/fetch-projects (:id team)) (dd/clear-selected-files))))] - (mf/with-effect - (let [node (mf/ref-val rowref) - mnt? (volatile! true) - sub (->> (wapi/observe-resize node) - (rx/observe-on :af) - (rx/subs (fn [entries] - (let [row (first entries) - row-rect (.-contentRect ^js row) - row-width (.-width ^js row-rect)] - (when @mnt? - (reset! width row-width))))))] - (fn [] - (vreset! mnt? false) - (rx/dispose! sub)))) - [:article.dashboard-project-row {:class (when first? "first")} [:header.project {:ref rowref} diff --git a/frontend/src/app/main/ui/dashboard/search.cljs b/frontend/src/app/main/ui/dashboard/search.cljs index bcbcfd710f..97644bcbca 100644 --- a/frontend/src/app/main/ui/dashboard/search.cljs +++ b/frontend/src/app/main/ui/dashboard/search.cljs @@ -6,16 +6,14 @@ (ns app.main.ui.dashboard.search (:require - [app.common.math :as mth] [app.main.data.dashboard :as dd] [app.main.refs :as refs] [app.main.store :as st] [app.main.ui.dashboard.grid :refer [grid]] + [app.main.ui.hooks :as hooks] [app.main.ui.icons :as i] [app.util.dom :as dom] [app.util.i18n :as i18n :refer [tr]] - [app.util.webapi :as wapi] - [beicon.core :as rx] [rumext.v2 :as mf])) (mf/defc search-page @@ -37,31 +35,7 @@ (dd/clear-selected-files)))) (let [result (mf/deref refs/dashboard-search-result) - width (mf/use-state nil) - rowref (mf/use-ref) - itemsize (if (>= @width 1030) - 280 - 230) - - ratio (if (some? @width) (/ @width itemsize) 0) - nitems (mth/floor ratio) - limit (min 10 nitems) - limit (max 1 limit)] - (mf/use-effect - (fn [] - (let [node (mf/ref-val rowref) - mnt? (volatile! true) - sub (->> (wapi/observe-resize node) - (rx/observe-on :af) - (rx/subs (fn [entries] - (let [row (first entries) - row-rect (.-contentRect ^js row) - row-width (.-width ^js row-rect)] - (when @mnt? - (reset! width row-width))))))] - (fn [] - (vreset! mnt? false) - (rx/dispose! sub))))) + [rowref limit] (hooks/use-dynamic-grid-item-width)] [:* [:header.dashboard-header [:div.dashboard-title#dashboard-search-title diff --git a/frontend/src/app/main/ui/hooks.cljs b/frontend/src/app/main/ui/hooks.cljs index 4963043dbc..dd0babf9f4 100644 --- a/frontend/src/app/main/ui/hooks.cljs +++ b/frontend/src/app/main/ui/hooks.cljs @@ -8,6 +8,7 @@ "A collection of general purpose react hooks." (:require [app.common.files.focus :as cpf] + [app.common.math :as mth] [app.main.broadcast :as mbc] [app.main.data.shortcuts :as dsc] [app.main.refs :as refs] @@ -16,6 +17,7 @@ [app.util.dom.dnd :as dnd] [app.util.storage :refer [storage]] [app.util.timers :as ts] + [app.util.webapi :as wapi] [beicon.core :as rx] [goog.functions :as f] [rumext.v2 :as mf])) @@ -345,3 +347,38 @@ state)) +(defn use-dynamic-grid-item-width + ([] + (use-dynamic-grid-item-width nil)) + + ([itemsize] + (let [width (mf/use-state (:items-width @storage)) + rowref (mf/use-ref) + + itemsize (cond + (some? itemsize) itemsize + (>= @width 1030) 280 + :else 230) + + ratio (if (some? @width) (/ @width itemsize) 0) + nitems (mth/floor ratio) + limit (min 10 nitems) + limit (max 1 limit)] + + (mf/with-effect + (let [node (mf/ref-val rowref) + mnt? (volatile! true) + sub (->> (wapi/observe-resize node) + (rx/observe-on :af) + (rx/subs (fn [entries] + (let [row (first entries) + row-rect (.-contentRect ^js row) + row-width (.-width ^js row-rect)] + (when @mnt? + (reset! width row-width) + (swap! storage assoc :items-width row-width))))))] + (fn [] + (vreset! mnt? false) + (rx/dispose! sub)))) + + [rowref limit]))) From c98f2628f031f9a32e6b06eb973fbcfcf6e3e866 Mon Sep 17 00:00:00 2001 From: "alonso.torres" Date: Mon, 27 Nov 2023 14:31:05 +0100 Subject: [PATCH 2/6] :sparkles: Add animate.css as library --- frontend/gulpfile.js | 6 +++++- frontend/package.json | 1 + frontend/resources/styles/main-default.scss | 1 + frontend/yarn.lock | 5 +++++ 4 files changed, 12 insertions(+), 1 deletion(-) diff --git a/frontend/gulpfile.js b/frontend/gulpfile.js index b94f72ee83..767ef69ecf 100644 --- a/frontend/gulpfile.js +++ b/frontend/gulpfile.js @@ -234,7 +234,11 @@ gulp.task("scss:modules", function () { gulp.task("scss:main", function () { return gulp .src(paths.resources + "styles/main-default.scss") - .pipe(gulpSass.sync().on("error", gulpSass.logError)) + .pipe(gulpSass.sync({ + includePaths: [ + "./node_modules/animate.css" + ] + })) .pipe(gulpPostcss([autoprefixer])) .pipe(gulp.dest(paths.output + "css/")); }); diff --git a/frontend/package.json b/frontend/package.json index 62402f8016..f9801e1553 100644 --- a/frontend/package.json +++ b/frontend/package.json @@ -41,6 +41,7 @@ "@storybook/react": "^7.5.3", "@storybook/react-vite": "^7.5.3", "@storybook/testing-library": "^0.2.2", + "animate.css": "^4.1.1", "autoprefixer": "^10.4.15", "concurrently": "^8.2.2", "cypress": "^10.3.0", diff --git a/frontend/resources/styles/main-default.scss b/frontend/resources/styles/main-default.scss index a6b6178c79..26695dd85c 100644 --- a/frontend/resources/styles/main-default.scss +++ b/frontend/resources/styles/main-default.scss @@ -23,6 +23,7 @@ @import "common/dependencies/z-index"; @import "common/dependencies/highlightjs-theme"; +@import "animate"; @import "common/refactor/color-defs.scss"; @import "common/refactor/themes.scss"; @import "common/refactor/design-tokens.scss"; diff --git a/frontend/yarn.lock b/frontend/yarn.lock index 8a2c9b5174..066b43cc44 100644 --- a/frontend/yarn.lock +++ b/frontend/yarn.lock @@ -3249,6 +3249,11 @@ aggregate-error@^3.0.0: clean-stack "^2.0.0" indent-string "^4.0.0" +animate.css@^4.1.1: + version "4.1.1" + resolved "https://registry.yarnpkg.com/animate.css/-/animate.css-4.1.1.tgz#614ec5a81131d7e4dc362a58143f7406abd68075" + integrity sha512-+mRmCTv6SbCmtYJCN4faJMNFVNN5EuCTTprDTAo7YzIGji2KADmakjVA3+8mVDkZ2Bf09vayB35lSQIex2+QaQ== + ansi-colors@^1.0.1: version "1.1.0" resolved "https://registry.yarnpkg.com/ansi-colors/-/ansi-colors-1.1.0.tgz#6374b4dd5d4718ff3ce27a671a3b1cad077132a9" From e3b096110fd3aafa527660f3eb769c87cd3ab6a9 Mon Sep 17 00:00:00 2001 From: "alonso.torres" Date: Fri, 17 Nov 2023 09:37:36 +0100 Subject: [PATCH 3/6] :lipstick: Move styles to modules --- .../styles/main/layouts/main-layout.scss | 36 +- .../main/ui/components/context_menu_a11y.cljs | 239 ++-- frontend/src/app/main/ui/dashboard.cljs | 226 +++- frontend/src/app/main/ui/dashboard.scss | 17 + .../src/app/main/ui/dashboard/comments.cljs | 139 +- .../src/app/main/ui/dashboard/comments.scss | 526 ++++++++ frontend/src/app/main/ui/dashboard/files.cljs | 214 ++- frontend/src/app/main/ui/dashboard/files.scss | 237 ++++ frontend/src/app/main/ui/dashboard/fonts.cljs | 472 ++++--- frontend/src/app/main/ui/dashboard/fonts.scss | 621 +++++++++ frontend/src/app/main/ui/dashboard/grid.cljs | 696 +++++++--- frontend/src/app/main/ui/dashboard/grid.scss | 517 +++++++ .../app/main/ui/dashboard/inline_edition.cljs | 34 +- .../app/main/ui/dashboard/inline_edition.scss | 0 .../src/app/main/ui/dashboard/libraries.cljs | 38 +- .../src/app/main/ui/dashboard/libraries.scss | 752 +++++++++++ .../app/main/ui/dashboard/placeholder.cljs | 65 +- .../app/main/ui/dashboard/placeholder.scss | 112 ++ .../src/app/main/ui/dashboard/projects.cljs | 506 ++++--- .../src/app/main/ui/dashboard/projects.scss | 909 +++++++++++++ .../src/app/main/ui/dashboard/search.cljs | 117 +- .../src/app/main/ui/dashboard/search.scss | 325 +++++ .../src/app/main/ui/dashboard/sidebar.cljs | 933 +++++++++---- .../src/app/main/ui/dashboard/sidebar.scss | 515 +++++++ frontend/src/app/main/ui/dashboard/team.cljs | 886 ++++++++---- frontend/src/app/main/ui/dashboard/team.scss | 1195 +++++++++++++++++ .../src/app/main/ui/dashboard/templates.cljs | 225 +++- .../src/app/main/ui/dashboard/templates.scss | 246 ++++ frontend/src/app/main/ui/settings.cljs | 77 +- frontend/src/app/main/ui/settings.scss | 697 ++++++++++ .../app/main/ui/settings/access_tokens.cljs | 178 ++- .../app/main/ui/settings/access_tokens.scss | 846 ++++++++++++ .../src/app/main/ui/settings/feedback.cljs | 125 +- .../src/app/main/ui/settings/feedback.scss | 690 ++++++++++ .../src/app/main/ui/settings/options.cljs | 85 +- .../src/app/main/ui/settings/options.scss | 642 +++++++++ .../src/app/main/ui/settings/password.cljs | 98 +- .../src/app/main/ui/settings/password.scss | 642 +++++++++ .../src/app/main/ui/settings/profile.cljs | 148 +- .../src/app/main/ui/settings/profile.scss | 642 +++++++++ .../src/app/main/ui/settings/sidebar.cljs | 152 ++- .../src/app/main/ui/settings/sidebar.scss | 922 +++++++++++++ 42 files changed, 14966 insertions(+), 1776 deletions(-) create mode 100644 frontend/src/app/main/ui/dashboard.scss create mode 100644 frontend/src/app/main/ui/dashboard/comments.scss create mode 100644 frontend/src/app/main/ui/dashboard/files.scss create mode 100644 frontend/src/app/main/ui/dashboard/fonts.scss create mode 100644 frontend/src/app/main/ui/dashboard/grid.scss create mode 100644 frontend/src/app/main/ui/dashboard/inline_edition.scss create mode 100644 frontend/src/app/main/ui/dashboard/libraries.scss create mode 100644 frontend/src/app/main/ui/dashboard/placeholder.scss create mode 100644 frontend/src/app/main/ui/dashboard/projects.scss create mode 100644 frontend/src/app/main/ui/dashboard/search.scss create mode 100644 frontend/src/app/main/ui/dashboard/sidebar.scss create mode 100644 frontend/src/app/main/ui/dashboard/templates.scss create mode 100644 frontend/src/app/main/ui/settings.scss create mode 100644 frontend/src/app/main/ui/settings/feedback.scss create mode 100644 frontend/src/app/main/ui/settings/options.scss create mode 100644 frontend/src/app/main/ui/settings/password.scss create mode 100644 frontend/src/app/main/ui/settings/profile.scss create mode 100644 frontend/src/app/main/ui/settings/sidebar.scss diff --git a/frontend/resources/styles/main/layouts/main-layout.scss b/frontend/resources/styles/main/layouts/main-layout.scss index a43404ff1d..a9ba4a0aeb 100644 --- a/frontend/resources/styles/main/layouts/main-layout.scss +++ b/frontend/resources/styles/main/layouts/main-layout.scss @@ -53,7 +53,7 @@ // NEW DASHBOARD CSS -.dashboard-layout-refactor { +.delete-me-dashboard-layout-refactor { background-color: $db-primary; display: grid; grid-template-rows: 50px 1fr; @@ -828,7 +828,7 @@ // Dashboard content .dashboard-project-row .project { background-color: transparent; - + h2 { color: $df-primary; font-weight: 400; @@ -852,7 +852,7 @@ border-color: transparent; margin: 0.8rem 15px; } - + .icon { svg { fill: $df-secondary; @@ -871,21 +871,21 @@ } } - .btn-secondary { - background-color: $db-tertiary; - text-transform: uppercase; - border: none; - color: $df-primary; - border-radius: 8px; - - &:hover { - background-color: $db-cuaternary; - color: $da-primary; - svg { - fill: $da-primary; - } - } - } + .btn-secondary { + background-color: $db-tertiary; + text-transform: uppercase; + border: none; + color: $df-primary; + border-radius: 8px; + + &:hover { + background-color: $db-cuaternary; + color: $da-primary; + svg { + fill: $da-primary; + } + } + } // File cards .dashboard-grid { diff --git a/frontend/src/app/main/ui/components/context_menu_a11y.cljs b/frontend/src/app/main/ui/components/context_menu_a11y.cljs index 8cd5536d2f..21d5bf8082 100644 --- a/frontend/src/app/main/ui/components/context_menu_a11y.cljs +++ b/frontend/src/app/main/ui/components/context_menu_a11y.cljs @@ -5,7 +5,7 @@ ;; Copyright (c) KALEIDOS INC (ns app.main.ui.components.context-menu-a11y - (:require-macros [app.main.style :refer [css]]) + (:require-macros [app.main.style :as stl]) (:require [app.common.data :as d] [app.common.data.macros :as dm] @@ -66,7 +66,6 @@ left (gobj/get props "left" 0) fixed? (gobj/get props "fixed?" false) min-width? (gobj/get props "min-width?" false) - workspace? (gobj/get props "workspace?" false) origin (gobj/get props "origin") route (mf/deref refs/route) new-css-system (mf/use-ctx ctx/new-css-system) @@ -192,107 +191,149 @@ (tm/schedule-on-idle #(dom/focus! (dom/get-element (first ids))))) - (when (and open? (some? (:levels @local))) - [:> dropdown' props + (if new-css-system + (when (and open? (some? (:levels @local))) + [:> dropdown' props + (let [level (-> @local :levels peek) + original-options (:options level) + parent-original (:parent-option level)] + [:div {:class (stl/css-case :is-selectable is-selectable + :context-menu true + :is-open open? + :fixed fixed?) + :style {:top (+ top (:offset-y @local)) + :left (+ left (:offset-x @local))} + :on-key-down (on-key-down original-options parent-original)} + (let [level (-> @local :levels peek)] + [:ul {:class (stl/css-case :min-width min-width? + :context-menu-items true) + :role "menu" + :ref check-menu-offscreen} + (when-let [parent-option (:parent-option level)] + [:* + [:& context-menu-a11y-item + {:id "go-back-sub-option" + :class (stl/css :context-menu-item) + :tab-index "0" + :on-key-down (fn [event] + (dom/prevent-default event))} + [:div {:class (stl/css :context-menu-action :submenu-back) + :data-no-close true + :on-click exit-submenu} + [:span {:class (stl/css :submenu-icon-back)} i/arrow-refactor] + parent-option]] - (let [level (-> @local :levels peek) - original-options (:options level) - parent-original (:parent-option level)] - [:div {:class (if (and new-css-system workspace?) - (dom/classnames (css :is-selectable) is-selectable - (css :context-menu) true - (css :is-open) open? - (css :fixed) fixed?) - (dom/classnames :is-selectable is-selectable + [:li {:class (stl/css :separator)}]]) + + (for [[index option] (d/enumerate (:options level))] + (let [option-name (:option-name option) + id (:id option) + sub-options (:sub-options option) + option-handler (:option-handler option) + data-test (:data-test option)] + (when option-name + (if (= option-name :separator) + [:li {:key (dm/str "context-item-" index) + :class (stl/css :separator)}] + [:& context-menu-a11y-item + {:id id + :key id + :class (stl/css-case + :is-selected (and selected (= option-name selected)) + :selected (and selected (= data-test selected)) + :context-menu-item true) + :key-index (dm/str "context-item-" index) + :tab-index "0" + :on-key-down (fn [event] + (dom/prevent-default event))} + (if-not sub-options + [:a {:class (stl/css :context-menu-action) + :on-click #(do (dom/stop-propagation %) + (on-close) + (option-handler %)) + :data-test data-test} + (if (and in-dashboard? (= option-name "Default")) + (tr "dashboard.default-team-name") + option-name) + + (when (and selected (= data-test selected)) + [:span {:class (stl/css :selected-icon)} i/tick-refactor])] + + [:a {:class (stl/css :context-menu-action :submenu) + :data-no-close true + :on-click (enter-submenu option-name sub-options) + :data-test data-test} + option-name + [:span {:class (stl/css :submenu-icon)} i/arrow-refactor]])]))))])])]) + + ;; OLD + (when (and open? (some? (:levels @local))) + [:> dropdown' props + + (let [level (-> @local :levels peek) + original-options (:options level) + parent-original (:parent-option level)] + [:div {:class (dom/classnames :is-selectable is-selectable :context-menu true :is-open open? - :fixed fixed?)) - :style {:top (+ top (:offset-y @local)) - :left (+ left (:offset-x @local))} - :on-key-down (on-key-down original-options parent-original)} - (let [level (-> @local :levels peek)] - [:ul {:class (if (and new-css-system workspace?) - (dom/classnames (css :min-width) min-width? - (css :context-menu-items) true) - (dom/classnames :min-width min-width? - :context-menu-items true)) - :role "menu" - :ref check-menu-offscreen} - (when-let [parent-option (:parent-option level)] - [:* - [:& context-menu-a11y-item - {:id "go-back-sub-option" - :class (dom/classnames (css :context-menu-item) (and new-css-system workspace?)) - :tab-index "0" - :on-key-down (fn [event] - (dom/prevent-default event))} - [:div {:class (if (and new-css-system workspace?) - (dom/classnames (css :context-menu-action) true - (css :submenu-back) true) - (dom/classnames :context-menu-action true - :submenu-back true)) - :data-no-close true - :on-click exit-submenu} - [:span {:class (dom/classnames (css :submenu-icon-back) (and new-css-system workspace?))} - (if (and new-css-system workspace?) - i/arrow-refactor - i/arrow-slide)] - parent-option]] - [:li {:class (if (and new-css-system workspace?) - (dom/classnames (css :separator) true) - (dom/classnames :separator true))}]]) - (for [[index option] (d/enumerate (:options level))] - (let [option-name (:option-name option) - id (:id option) - sub-options (:sub-options option) - option-handler (:option-handler option) - data-test (:data-test option)] - (when option-name - (if (= option-name :separator) - [:li {:key (dm/str "context-item-" index) - :class (if (and new-css-system workspace?) - (dom/classnames (css :separator) true) - (dom/classnames :separator true))}] - [:& context-menu-a11y-item - {:id id - :key id - :class (if (and new-css-system workspace?) - (dom/classnames (css :is-selected) (and selected (= option-name selected)) - (css :selected) (and selected (= data-test selected)) - (css :context-menu-item) true) - (dom/classnames :is-selected (and selected (= option-name selected)))) - :key-index (dm/str "context-item-" index) - :tab-index "0" - :on-key-down (fn [event] - (dom/prevent-default event))} - (if-not sub-options - [:a {:class (if (and new-css-system workspace?) - (dom/classnames (css :context-menu-action) true) - (dom/classnames :context-menu-action true)) - :on-click #(do (dom/stop-propagation %) - (on-close) - (option-handler %)) - :data-test data-test} - (if (and in-dashboard? (= option-name "Default")) - (tr "dashboard.default-team-name") - option-name) + :fixed fixed?) + :style {:top (+ top (:offset-y @local)) + :left (+ left (:offset-x @local))} + :on-key-down (on-key-down original-options parent-original)} + (let [level (-> @local :levels peek)] + [:ul {:class (dom/classnames :min-width min-width? + :context-menu-items true) + :role "menu" + :ref check-menu-offscreen} + (when-let [parent-option (:parent-option level)] + [:* + [:& context-menu-a11y-item + {:id "go-back-sub-option" + :tab-index "0" + :on-key-down (fn [event] + (dom/prevent-default event))} + [:div {:class (dom/classnames :context-menu-action true + :submenu-back true) + :data-no-close true + :on-click exit-submenu} + [:span i/arrow-slide] - (when (and new-css-system selected (= data-test selected)) - [:span {:class (dom/classnames (css :selected-icon) true)} - i/tick-refactor])] - [:a {:class (if (and new-css-system workspace?) - (dom/classnames (css :context-menu-action) true - (css :submenu) true) - (dom/classnames :context-menu-action true - :submenu true)) - :data-no-close true - :on-click (enter-submenu option-name sub-options) - :data-test data-test} - option-name - [:span {:class (dom/classnames (css :submenu-icon) (and new-css-system workspace?))} - (if (and new-css-system workspace?) - i/arrow-refactor - i/arrow-slide)]])]))))])])]))) + parent-option]] + + [:li.separator]]) + + (for [[index option] (d/enumerate (:options level))] + (let [option-name (:option-name option) + id (:id option) + sub-options (:sub-options option) + option-handler (:option-handler option) + data-test (:data-test option)] + (when option-name + (if (= option-name :separator) + [:li.separator {:key (dm/str "context-item-" index)}] + [:& context-menu-a11y-item + {:id id + :key id + :class (dom/classnames :is-selected (and selected (= option-name selected))) + :key-index (dm/str "context-item-" index) + :tab-index "0" + :on-key-down (fn [event] + (dom/prevent-default event))} + (if-not sub-options + [:a {:class (dom/classnames :context-menu-action true) + :on-click #(do (dom/stop-propagation %) + (on-close) + (option-handler %)) + :data-test data-test} + (if (and in-dashboard? (= option-name "Default")) + (tr "dashboard.default-team-name") + option-name)] + [:a.context-menu-action.submenu + {:data-no-close true + :on-click (enter-submenu option-name sub-options) + :data-test data-test} + option-name + [:span i/arrow-slide]])]))))])])])))) (mf/defc context-menu-a11y {::mf/wrap-props false} diff --git a/frontend/src/app/main/ui/dashboard.cljs b/frontend/src/app/main/ui/dashboard.cljs index 22fd5d5247..4b7bc7bdf3 100644 --- a/frontend/src/app/main/ui/dashboard.cljs +++ b/frontend/src/app/main/ui/dashboard.cljs @@ -5,6 +5,7 @@ ;; Copyright (c) KALEIDOS INC (ns app.main.ui.dashboard + (:require-macros [app.main.style :as stl]) (:require [app.common.data :as d] [app.common.spec :as us] @@ -52,7 +53,8 @@ (mf/defc dashboard-content [{:keys [team projects project section search-term profile] :as props}] - (let [container (mf/use-ref) + (let [new-css-system (mf/use-ctx ctx/new-css-system) + container (mf/use-ref) content-width (mf/use-state 0) project-id (:id project) team-id (:id team) @@ -81,60 +83,118 @@ (mf/use-effect on-resize) - [:div.dashboard-content {:on-click clear-selected-fn :ref container} - (case section - :dashboard-projects - [:* - [:& projects-section - {:team team - :projects projects - :profile profile - :default-project-id default-project-id}] - - (when (contains? cf/flags :dashboard-templates-section) - [:& templates-section {:profile profile - :project-id project-id - :team-id team-id - :default-project-id default-project-id - :content-width @content-width}])] - - :dashboard-fonts - [:& fonts-page {:team team}] - - :dashboard-font-providers - [:& font-providers-page {:team team}] - - :dashboard-files - (when project + (if new-css-system + [:div {:class (stl/css :dashboard-content) + :on-click clear-selected-fn :ref container} + (case section + :dashboard-projects [:* - [:& files-section {:team team :project project}] + [:& projects-section + {:team team + :projects projects + :profile profile + :default-project-id default-project-id}] + (when (contains? cf/flags :dashboard-templates-section) [:& templates-section {:profile profile - :team-id team-id :project-id project-id + :team-id team-id :default-project-id default-project-id - :content-width @content-width}])]) + :content-width @content-width}])] - :dashboard-search - [:& search-page {:team team - :search-term search-term}] + :dashboard-fonts + [:& fonts-page {:team team}] - :dashboard-libraries - [:& libraries-page {:team team}] + :dashboard-font-providers + [:& font-providers-page {:team team}] - :dashboard-team-members - [:& team-members-page {:team team :profile profile}] + :dashboard-files + (when project + [:* + [:& files-section {:team team :project project}] + (when (contains? cf/flags :dashboard-templates-section) + [:& templates-section {:profile profile + :team-id team-id + :project-id project-id + :default-project-id default-project-id + :content-width @content-width}])]) - :dashboard-team-invitations - [:& team-invitations-page {:team team}] + :dashboard-search + [:& search-page {:team team + :search-term search-term}] - :dashboard-team-webhooks - [:& team-webhooks-page {:team team}] + :dashboard-libraries + [:& libraries-page {:team team}] - :dashboard-team-settings - [:& team-settings-page {:team team :profile profile}] + :dashboard-team-members + [:& team-members-page {:team team :profile profile}] - nil)])) + :dashboard-team-invitations + [:& team-invitations-page {:team team}] + + :dashboard-team-webhooks + [:& team-webhooks-page {:team team}] + + :dashboard-team-settings + [:& team-settings-page {:team team :profile profile}] + + nil)] + + ;; OLD + [:div.dashboard-content {:on-click clear-selected-fn :ref container} + (case section + :dashboard-projects + [:* + [:& projects-section + {:team team + :projects projects + :profile profile + :default-project-id default-project-id}] + + (when (contains? cf/flags :dashboard-templates-section) + [:& templates-section {:profile profile + :project-id project-id + :team-id team-id + :default-project-id default-project-id + :content-width @content-width}])] + + :dashboard-fonts + [:& fonts-page {:team team}] + + :dashboard-font-providers + [:& font-providers-page {:team team}] + + :dashboard-files + (when project + [:* + [:& files-section {:team team :project project}] + (when (contains? cf/flags :dashboard-templates-section) + [:& templates-section {:profile profile + :team-id team-id + :project-id project-id + :default-project-id default-project-id + :content-width @content-width}])]) + + :dashboard-search + [:& search-page {:team team + :search-term search-term}] + + :dashboard-libraries + [:& libraries-page {:team team}] + + :dashboard-team-members + [:& team-members-page {:team team :profile profile}] + + :dashboard-team-invitations + [:& team-invitations-page {:team team}] + + :dashboard-team-webhooks + [:& team-webhooks-page {:team team}] + + :dashboard-team-settings + [:& team-settings-page {:team team :profile profile}] + + nil)]))) (mf/defc dashboard [{:keys [route profile] :as props}] @@ -168,31 +228,59 @@ (fn [] (events/unlistenByKey key)))) - [:& (mf/provider ctx/current-team-id) {:value team-id} - [:& (mf/provider ctx/current-project-id) {:value project-id} - ;; NOTE: dashboard events and other related functions assumes - ;; that the team is a implicit context variable that is - ;; available using react context or accessing - ;; the :current-team-id on the state. We set the key to the - ;; team-id because we want to completely refresh all the - ;; components on team change. Many components assumes that the - ;; team is already set so don't put the team into mf/deps. - (when team - [:main {:class (dom/classnames :dashboard-layout (not new-css-system) - :dashboard-layout-refactor new-css-system) - :key (:id team)} - [:& sidebar - {:team team - :projects projects - :project project - :profile profile - :section section - :search-term search-term}] - (when (and team profile (seq projects)) - [:& dashboard-content - {:projects projects - :profile profile + (if new-css-system + [:& (mf/provider ctx/current-team-id) {:value team-id} + [:& (mf/provider ctx/current-project-id) {:value project-id} + ;; NOTE: dashboard events and other related functions assumes + ;; that the team is a implicit context variable that is + ;; available using react context or accessing + ;; the :current-team-id on the state. We set the key to the + ;; team-id because we want to completely refresh all the + ;; components on team change. Many components assumes that the + ;; team is already set so don't put the team into mf/deps. + (when team + [:main {:class (stl/css :dashboard-layout-refactor :dashboard) + :key (:id team)} + [:& sidebar + {:team team + :projects projects :project project + :profile profile :section section - :search-term search-term - :team team}])])]])) + :search-term search-term}] + (when (and team profile (seq projects)) + [:& dashboard-content + {:projects projects + :profile profile + :project project + :section section + :search-term search-term + :team team}])])]] + + [:& (mf/provider ctx/current-team-id) {:value team-id} + [:& (mf/provider ctx/current-project-id) {:value project-id} + ;; NOTE: dashboard events and other related functions assumes + ;; that the team is a implicit context variable that is + ;; available using react context or accessing + ;; the :current-team-id on the state. We set the key to the + ;; team-id because we want to completely refresh all the + ;; components on team change. Many components assumes that the + ;; team is already set so don't put the team into mf/deps. + (when team + [:main {:class (dom/classnames :dashboard-layout true) :key (:id team)} + [:& sidebar + {:team team + :projects projects + :project project + :profile profile + :section section + :search-term search-term}] + (when (and team profile (seq projects)) + [:& dashboard-content + {:projects projects + :profile profile + :project project + :section section + :search-term search-term + :team team}])])]]))) + diff --git a/frontend/src/app/main/ui/dashboard.scss b/frontend/src/app/main/ui/dashboard.scss new file mode 100644 index 0000000000..71d4d91e2b --- /dev/null +++ b/frontend/src/app/main/ui/dashboard.scss @@ -0,0 +1,17 @@ +@import "common/dependencies/colors"; + +.dashboard { + background-color: $db-primary; + display: grid; + grid-template-rows: 50px 1fr; + grid-template-columns: 40px 256px 1fr; + height: 100vh; +} + +.dashboard-content { + display: flex; + flex-direction: column; + position: relative; + grid-row: 1 / span 2; + padding: 1rem 1rem 0 0; +} diff --git a/frontend/src/app/main/ui/dashboard/comments.cljs b/frontend/src/app/main/ui/dashboard/comments.cljs index dc92961ddf..4b1815b3a8 100644 --- a/frontend/src/app/main/ui/dashboard/comments.cljs +++ b/frontend/src/app/main/ui/dashboard/comments.cljs @@ -5,6 +5,7 @@ ;; Copyright (c) KALEIDOS INC (ns app.main.ui.dashboard.comments + (:require-macros [app.main.style :as stl]) (:require [app.main.data.comments :as dcm] [app.main.data.events :as ev] @@ -13,6 +14,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.util.dom :as dom] [app.util.i18n :as i18n :refer [tr]] @@ -22,7 +24,8 @@ (mf/defc comments-section [{:keys [profile team]}] - (let [show-dropdown? (mf/use-state false) + (let [new-css-system (mf/use-ctx ctx/new-css-system) + show-dropdown? (mf/use-state false) show-dropdown (mf/use-fn #(reset! show-dropdown? true)) hide-dropdown (mf/use-fn #(reset! show-dropdown? false)) threads-map (mf/deref refs/comment-threads) @@ -53,50 +56,102 @@ (st/emit! (ptk/event ::ev/event {::ev/name "open-comment-notifications" ::ev/origin "dashboard"}))))) - [:div.dashboard-comments-section - [:div.button - {:tab-index "0" - :on-click show-dropdown - :on-key-down (fn [event] - (when (kbd/enter? event) - (show-dropdown event))) - :data-test "open-comments" - :class (dom/classnames :open @show-dropdown? + (if new-css-system + [:div {:class (stl/css :dashboard-comments-section)} + [:div + {:tab-index "0" + :on-click show-dropdown + :on-key-down (fn [event] + (when (kbd/enter? event) + (show-dropdown event))) + :data-test "open-comments" + :class (stl/css-case :button true + :open @show-dropdown? :unread (boolean (seq tgroups)))} - i/chat] + i/chat] - [:& dropdown {:show @show-dropdown? :on-close hide-dropdown} - [:div.dropdown.comments-section.comment-threads-section. - [:div.header - [:h3 (tr "labels.comments")] - [:span.close {:tab-index (if @show-dropdown? - "0" - "-1") - :on-click hide-dropdown - :on-key-down (fn [event] - (when (kbd/enter? event) - (hide-dropdown event)))} i/close]] + [:& dropdown {:show @show-dropdown? :on-close hide-dropdown} + [:div {:class (stl/css :dropdown :comments-section :comment-threads-section)} + [:div {:class (stl/css :header)} + [:h3 (tr "labels.comments")] + [:span {:class (stl/css :close) + :tab-index (if @show-dropdown? + "0" + "-1") + :on-click hide-dropdown + :on-key-down (fn [event] + (when (kbd/enter? event) + (hide-dropdown event)))} i/close]] - [:hr] + [:hr] - (if (seq tgroups) - [:div.thread-groups - [:& cmt/comment-thread-group - {:group (first tgroups) - :on-thread-click on-navigate - :show-file-name true - :users users}] - (for [tgroup (rest tgroups)] - [:* - [:hr] + (if (seq tgroups) + [:div {:class (stl/css :thread-groups)} + [:& cmt/comment-thread-group + {:group (first tgroups) + :on-thread-click on-navigate + :show-file-name true + :users users}] + (for [tgroup (rest tgroups)] + [:* + [:hr] - [:& cmt/comment-thread-group - {:group tgroup - :on-thread-click on-navigate - :show-file-name true - :users users - :key (:page-id tgroup)}]])] + [:& cmt/comment-thread-group + {:group tgroup + :on-thread-click on-navigate + :show-file-name true + :users users + :key (:page-id tgroup)}]])] - [:div.thread-groups-placeholder - i/chat - (tr "labels.no-comments-available")])]]])) + [:div {:class (stl/css :thread-groups-placeholder)} + i/chat + (tr "labels.no-comments-available")])]]] + + ;; OLD + [:div.dashboard-comments-section + [:div.button + {:tab-index "0" + :on-click show-dropdown + :on-key-down (fn [event] + (when (kbd/enter? event) + (show-dropdown event))) + :data-test "open-comments" + :class (dom/classnames :open @show-dropdown? + :unread (boolean (seq tgroups)))} + i/chat] + + [:& dropdown {:show @show-dropdown? :on-close hide-dropdown} + [:div.dropdown.comments-section.comment-threads-section. + [:div.header + [:h3 (tr "labels.comments")] + [:span.close {:tab-index (if @show-dropdown? + "0" + "-1") + :on-click hide-dropdown + :on-key-down (fn [event] + (when (kbd/enter? event) + (hide-dropdown event)))} i/close]] + + [:hr] + + (if (seq tgroups) + [:div.thread-groups + [:& cmt/comment-thread-group + {:group (first tgroups) + :on-thread-click on-navigate + :show-file-name true + :users users}] + (for [tgroup (rest tgroups)] + [:* + [:hr] + + [:& cmt/comment-thread-group + {:group tgroup + :on-thread-click on-navigate + :show-file-name true + :users users + :key (:page-id tgroup)}]])] + + [:div.thread-groups-placeholder + i/chat + (tr "labels.no-comments-available")])]]]))) diff --git a/frontend/src/app/main/ui/dashboard/comments.scss b/frontend/src/app/main/ui/dashboard/comments.scss new file mode 100644 index 0000000000..e16952e48e --- /dev/null +++ b/frontend/src/app/main/ui/dashboard/comments.scss @@ -0,0 +1,526 @@ +@import "common/dependencies/colors"; +$fs12: 0.75rem; +$fs14: 0.875rem; +$size-2: 0.5rem; +$size-4: 1rem; +$size-5: 1.5rem; +$br2: 2px; +$br3: 3px; +$fw400: 400; +$fw700: 700; + +.dropdown { + position: absolute; + max-height: 30rem; + background-color: #ffffff; + border-radius: 2px; + box-shadow: 0px 2px 8px rgba(0, 0, 0, 0.25); + z-index: 12; + + background-color: #212426; + border: 1px solid #2e3434; + border-radius: 8px; + min-width: 252px; + + hr { + margin: 0; + border-color: #e3e3e3; + } +} + +.comments-section { + .thread-bubble { + position: absolute; + display: flex; + transform: translate(-15px, -15px); + + cursor: pointer; + pointer-events: auto; + background-color: $color-gray-10; + color: $color-gray-60; + border: 1px solid #b1b2b5; + box-sizing: border-box; + box-shadow: 0px 4px 4px rgba($color-black, 0.25); + + font-size: $fs12; + width: 30px; + height: 30px; + border-radius: 50%; + + display: flex; + align-items: center; + justify-content: center; + + &.resolved { + color: $color-gray-10; + background-color: $color-gray-50; + } + + &.unread { + background-color: $color-primary; + } + span { + user-select: none; + } + } + + .thread-content { + position: absolute; + pointer-events: auto; + margin-left: 10px; + background: $color-white; + border: 1px solid $color-gray-20; + box-sizing: border-box; + box-shadow: 0px 2px 8px rgba($color-black, 0.25); + border-radius: $br2; + min-width: 280px; + max-width: 280px; + user-select: text; + + .comments { + max-height: 420px; + min-height: 105px; + overflow-y: auto; + } + + hr { + border: 0; + height: 1px; + background-color: $color-gray-20; + margin: 0px 10px; + } + } + + .reply-form { + display: flex; + padding: 10px; + flex-direction: column; + + &.edit-form { + padding-bottom: 0px; + } + + textarea { + font-family: "worksans", sans-serif; + font-size: $fs12; + min-height: 32px; + outline: none; + overflow: hidden; + padding: $size-2; + resize: none; + width: 100%; + border-radius: $br2; + border: 1px solid $color-gray-20; + max-height: 4rem; + } + + .buttons { + margin-top: 10px; + display: flex; + justify-content: flex-end; + + input { + margin: 0px; + font-size: $fs14; + + &:not(:last-child) { + margin-right: 6px; + } + } + } + } + + .comment-container { + position: relative; + } + + .comment { + display: flex; + flex-direction: column; + padding: $size-4 $size-2; + + .author { + display: flex; + align-items: center; + height: 26px; + max-height: 26px; + position: relative; + + .name { + display: flex; + flex-direction: column; + + .fullname { + font-weight: $fw700; + color: $color-gray-60; + font-size: $fs12; + + // @include text-ellipsis; + width: 174px; + } + .timeago { + margin-top: -2px; + font-size: $fs12; + color: $color-gray-30; + } + } + + .avatar { + display: flex; + align-items: center; + padding-right: 6px; + + img { + border-radius: 50%; + flex-shrink: 0; + height: 24px; + width: 24px; + } + } + + .options-resolve { + position: absolute; + right: 20px; + top: 0px; + width: 16px; + height: 16px; + + cursor: pointer; + + svg { + width: 16px; + height: 16px; + fill: $color-gray-30; + } + } + + .options { + position: absolute; + right: -2px; + top: 2px; + height: 16px; + display: flex; + align-items: center; + cursor: pointer; + + .options-icon { + svg { + width: 14px; + height: 14px; + fill: $color-black; + } + } + } + } + + .content { + margin: $size-4 0; + font-size: $fs14; + color: $color-black; + .text { + margin: 0 $size-2 0 26px; + white-space: pre-wrap; + display: inline-block; + word-break: break-word; + } + } + } + + .comment-options-dropdown { + top: 7px; + right: 7px; + width: 150px; + + border: 1px solid #b1b2b5; + } +} + +.workspace-comment-threads-sidebar-header { + display: flex; + background-color: $color-black; + height: 34px; + align-items: center; + padding: 0px 9px; + color: $color-gray-10; + font-size: $fs12; + justify-content: space-between; + + .options { + display: flex; + margin-right: 3px; + cursor: pointer; + + .label { + padding-right: 8px; + } + + .icon { + display: flex; + align-items: center; + } + + svg { + fill: $color-gray-10; + width: 10px; + height: 10px; + } + } + + .dropdown { + top: 80px; + right: 7px; + } +} + +.comment-threads-section { + pointer-events: auto; + + .thread-groups { + height: calc(100% - 34px); + overflow-y: scroll; + hr { + border: 0; + height: 1px; + background-color: $color-gray-30; + margin: 0px 0px; + } + } + + .thread-group { + display: flex; + flex-direction: column; + font-size: $fs12; + + .section-title { + margin: 0px 10px; + margin-top: 15px; + + .icon { + margin-right: 4px; + } + + .label { + &.filename { + font-weight: $fw700; + } + } + + svg { + fill: $color-gray-10; + height: 10px; + width: 10px; + } + } + } + + .thread-bubble { + position: unset; + transform: unset; + width: 24px; + height: 24px; + margin-right: 6px; + box-shadow: unset; + } + + .comment { + cursor: pointer; + .author { + margin-bottom: $size-4; + .name { + display: flex; + + .fullname { + width: unset; + max-width: 170px; + color: $color-gray-20; + padding-right: 3px; + } + .timeago { + margin-top: unset; + color: $color-gray-20; + } + } + } + + .content { + margin-top: 0px; + color: $color-white; + + &.replies { + margin: 0 $size-2 0 26px; + display: flex; + .total-replies { + margin-right: 9px; + color: $color-info; + } + + .new-replies { + color: $color-primary; + } + } + } + } +} + +.viewer-comments-container { + width: 100%; + height: 100%; + z-index: 1; + position: absolute; + top: 0px; + left: 0px; +} + +.workspace-comments-container { + width: 100%; + height: 100%; + grid-column: 1 / span 2; + grid-row: 1 / span 2; + z-index: 1000; + pointer-events: none; + overflow: hidden; + user-select: text; + + .threads { + position: absolute; + top: 0px; + left: 0px; + } +} + +.dashboard-comments-section { + width: 25px; + height: 25px; + display: flex; + align-items: center; + justify-content: center; + background-color: $color-dashboard; + border-radius: $br3; + position: relative; + + .button { + width: 25px; + height: 25px; + display: flex; + align-items: center; + justify-content: center; + background-color: $color-dashboard; + border-radius: $br3; + + svg { + width: 15px; + height: 15px; + } + + &.unread { + background-color: $color-warning; + svg { + fill: #2e3434; + } + } + + &.open { + background-color: $color-black; + svg { + fill: $color-primary; + } + } + } + + .dropdown { + width: 280px; + bottom: 35px; + left: 0px; + } + + .header { + display: flex; + height: 40px; + align-items: center; + padding: 0px 11px; + + h3 { + font-weight: $fw400; + color: $color-black; + font-size: $fs14; + // line-height: $lh-128; // Original value was $fs18 => 1.125rem = 18px; 18px/14px = 128.571428571% => $lh-128 (rounded) + flex-grow: 1; + } + + .close { + display: flex; + align-items: center; + } + + svg { + width: 15px; + height: 15px; + transform: rotate(45deg); + } + } + + .thread-groups { + max-height: calc(30rem - 40px); + overflow: auto; + + hr { + background-color: $color-gray-10; + } + } + + .thread-group .section-title { + color: $color-black; + } + + .comment { + .author .name .fullname { + color: $color-gray-40; + } + .content { + color: $color-black; + } + } +} + +.thread-groups-placeholder { + align-items: center; + display: flex; + flex-direction: column; + font-size: $fs12; + padding: $size-5; + text-align: center; + + svg { + fill: $color-gray-20; + height: 24px; + margin-bottom: $size-5; + width: 24px; + } +} + +.dashboard-comments-section { + border-color: transparent; + border-radius: 8px; + background-color: $db-primary; + height: 32px; + width: 32px; + + .button { + border-radius: 8px; + background-color: $db-primary; + height: 32px; + width: 32px; + + svg { + fill: $df-secondary; + } + + &:hover { + background-color: $db-cuaternary; + + svg { + fill: $da-primary; + } + } + } +} diff --git a/frontend/src/app/main/ui/dashboard/files.cljs b/frontend/src/app/main/ui/dashboard/files.cljs index d7646d5b6e..7faf96b97e 100644 --- a/frontend/src/app/main/ui/dashboard/files.cljs +++ b/frontend/src/app/main/ui/dashboard/files.cljs @@ -5,11 +5,13 @@ ;; Copyright (c) KALEIDOS INC (ns app.main.ui.dashboard.files + (:require-macros [app.main.style :as stl]) (:require [app.main.data.dashboard :as dd] [app.main.data.events :as ev] [app.main.refs :as refs] [app.main.store :as st] + [app.main.ui.context :as ctx] [app.main.ui.dashboard.grid :refer [grid]] [app.main.ui.dashboard.inline-edition :refer [inline-edition]] [app.main.ui.dashboard.project-menu :refer [project-menu]] @@ -24,7 +26,8 @@ (mf/defc header [{:keys [project create-fn] :as props}] - (let [local (mf/use-state + (let [new-css-system (mf/use-ctx ctx/new-css-system) + local (mf/use-state {:menu-open false :edition false}) @@ -61,68 +64,137 @@ (dd/clear-selected-files))))] - [:header.dashboard-header - (if (:is-default project) - [:div.dashboard-title#dashboard-drafts-title - [:h1 (tr "labels.drafts")]] + (if new-css-system + [:header {:class (stl/css :dashboard-header)} + (if (:is-default project) + [:div#dashboard-drafts-title {:class (stl/css :dashboard-title)} + [:h1 (tr "labels.drafts")]] - (if (:edition @local) - [:& inline-edition {:content (:name project) - :on-end (fn [name] - (let [name (str/trim name)] - (when-not (str/empty? name) - (st/emit! (-> (dd/rename-project (assoc project :name name)) - (with-meta {::ev/origin "project"})))) - (swap! local assoc :edition false)))}] - [:div.dashboard-title - [:h1 {:on-double-click on-edit - :data-test "project-title" - :id (:id project)} - (:name project)]])) + (if (:edition @local) + [:& inline-edition + {:content (:name project) + :on-end (fn [name] + (let [name (str/trim name)] + (when-not (str/empty? name) + (st/emit! (-> (dd/rename-project (assoc project :name name)) + (with-meta {::ev/origin "project"})))) + (swap! local assoc :edition false)))}] + [:div {:class (stl/css :dashboard-title)} + [:h1 {:on-double-click on-edit + :data-test "project-title" + :id (:id project)} + (:name project)]])) - [:& project-menu {:project project - :show? (:menu-open @local) - :left (- (:x (:menu-pos @local)) 180) - :top (:y (:menu-pos @local)) - :on-edit on-edit - :on-menu-close on-menu-close - :on-import on-import}] + [:& project-menu {:project project + :show? (:menu-open @local) + :left (- (:x (:menu-pos @local)) 180) + :top (:y (:menu-pos @local)) + :on-edit on-edit + :on-menu-close on-menu-close + :on-import on-import}] - [:div.dashboard-header-actions - [:a.btn-secondary.btn-small - {:tab-index "0" - :on-click on-create-click - :data-test "new-file" - :on-key-down (fn [event] - (when (kbd/enter? event) - (on-create-click event)))} - (tr "dashboard.new-file")] - - (when-not (:is-default project) - [:button.icon.pin-icon.tooltip.tooltip-bottom - {:tab-index "0" - :class (when (:is-pinned project) "active") - :on-click toggle-pin - :alt (tr "dashboard.pin-unpin") + [:div {:class (stl/css :dashboard-header-actions)} + [:a + {:class (stl/css :btn-secondary :btn-small) + :tab-index "0" + :on-click on-create-click + :data-test "new-file" :on-key-down (fn [event] (when (kbd/enter? event) - (toggle-pin event)))} - (if (:is-pinned project) - i/pin-fill - i/pin)]) + (on-create-click event)))} + (tr "dashboard.new-file")] - [:div.icon.tooltip.tooltip-bottom-left - {:tab-index "0" - :on-click on-menu-click - :alt (tr "dashboard.options") - :on-key-down (fn [event] - (when (kbd/enter? event) - (on-menu-click event)))} - i/actions]]])) + (when-not (:is-default project) + [:button + {:class (stl/css-case :icon true + :pin-icon true + :tooltip true + :tooltip-bottom true + :active (:is-pinned project)) + :tab-index "0" + :on-click toggle-pin + :alt (tr "dashboard.pin-unpin") + :on-key-down (fn [event] + (when (kbd/enter? event) + (toggle-pin event)))} + (if (:is-pinned project) + i/pin-fill + i/pin)]) + + [:div + {:class (stl/css :icon :tooltip :tooltip-bottom-left) + :tab-index "0" + :on-click on-menu-click + :alt (tr "dashboard.options") + :on-key-down (fn [event] + (when (kbd/enter? event) + (on-menu-click event)))} + i/actions]]] + + ;; OLD + [:header.dashboard-header + (if (:is-default project) + [:div.dashboard-title#dashboard-drafts-title + [:h1 (tr "labels.drafts")]] + + (if (:edition @local) + [:& inline-edition {:content (:name project) + :on-end (fn [name] + (let [name (str/trim name)] + (when-not (str/empty? name) + (st/emit! (-> (dd/rename-project (assoc project :name name)) + (with-meta {::ev/origin "project"})))) + (swap! local assoc :edition false)))}] + [:div.dashboard-title + [:h1 {:on-double-click on-edit + :data-test "project-title" + :id (:id project)} + (:name project)]])) + + [:& project-menu {:project project + :show? (:menu-open @local) + :left (- (:x (:menu-pos @local)) 180) + :top (:y (:menu-pos @local)) + :on-edit on-edit + :on-menu-close on-menu-close + :on-import on-import}] + + [:div.dashboard-header-actions + [:a.btn-secondary.btn-small + {:tab-index "0" + :on-click on-create-click + :data-test "new-file" + :on-key-down (fn [event] + (when (kbd/enter? event) + (on-create-click event)))} + (tr "dashboard.new-file")] + + (when-not (:is-default project) + [:button.icon.pin-icon.tooltip.tooltip-bottom + {:tab-index "0" + :class (when (:is-pinned project) "active") + :on-click toggle-pin + :alt (tr "dashboard.pin-unpin") + :on-key-down (fn [event] + (when (kbd/enter? event) + (toggle-pin event)))} + (if (:is-pinned project) + i/pin-fill + i/pin)]) + + [:div.icon.tooltip.tooltip-bottom-left + {:tab-index "0" + :on-click on-menu-click + :alt (tr "dashboard.options") + :on-key-down (fn [event] + (when (kbd/enter? event) + (on-menu-click event)))} + i/actions]]]))) (mf/defc files-section [{:keys [project team] :as props}] - (let [files-map (mf/deref refs/dashboard-files) + (let [new-css-system (mf/use-ctx ctx/new-css-system) + files-map (mf/deref refs/dashboard-files) project-id (:id project) [rowref limit] (hooks/use-dynamic-grid-item-width) @@ -161,14 +233,28 @@ (st/emit! (dd/fetch-files {:project-id project-id}) (dd/clear-selected-files))) - [:* - [:& header {:team team - :project project - :create-fn create-file}] - [:section.dashboard-container.no-bg {:ref rowref} - [:& grid {:project project - :files files - :origin :files - :create-fn create-file - :limit limit}]]])) + (if new-css-system + [:* + [:& header {:team team + :project project + :create-fn create-file}] + [:section {:class (stl/css :dashboard-container :no-bg) + :ref rowref} + [:& grid {:project project + :files files + :origin :files + :create-fn create-file + :limit limit}]]] + + ;; OLD + [:* + [:& header {:team team + :project project + :create-fn create-file}] + [:section.dashboard-container.no-bg {:ref rowref} + [:& grid {:project project + :files files + :origin :files + :create-fn create-file + :limit limit}]]]))) diff --git a/frontend/src/app/main/ui/dashboard/files.scss b/frontend/src/app/main/ui/dashboard/files.scss new file mode 100644 index 0000000000..6e68a7bc9c --- /dev/null +++ b/frontend/src/app/main/ui/dashboard/files.scss @@ -0,0 +1,237 @@ +@import "common/dependencies/colors"; + +// FIXME: Mostly duplcated from projects.css + +$br3: 3px; +$fs14: 0.875rem; +$fs18: 1.125rem; +$fs22: 1.375rem; +$fw400: 400; +$fw600: 600; +$lh-088: 0.88; +$lh-115: 1.15; // original $title-lh-sm +$size-1: 0.25rem; +$size-2: 0.5rem; +$size-4: 1rem; +$size-5: 1.5rem; +$size-6: 2rem; + +.dashboard-container { + background-color: $color-dashboard; + flex: 1 0 0; + margin-right: $size-4; + overflow-y: auto; + width: 100%; + &.dashboard-projects { + user-select: none; + } + &.no-bg { + background-color: transparent; + } + &.dashboard-shared { + width: calc(100vw - 320px); + margin-right: 50px; + } + + &.search { + margin-top: 10px; + } +} + +.dashboard-header { + display: flex; + align-items: center; + justify-content: space-between; + background-color: $color-white; + height: 63px; + padding: $size-1 $size-4 $size-1 $size-2; + position: relative; + z-index: 10; + user-select: none; + &.team { + display: grid; + grid-template-columns: 20% 1fr 20%; + } + + .element-name { + margin-right: $size-2; + } + + .btn-secondary { + flex-shrink: 0; + z-index: 10; + height: 32px; + } + + svg { + fill: $color-black; + height: 14px; + margin-right: $size-1; + width: 14px; + } + + nav { + display: flex; + align-items: flex-end; + justify-content: center; + z-index: 1; + + ul { + display: flex; + font-size: $fs14; + justify-content: center; + margin: 0; + } + + li { + a { + display: flex; + align-items: center; + flex-basis: 140px; + border-bottom: 3px solid transparent; + color: $color-gray-30; + height: 40px; + padding: $size-1 $size-5; + font-weight: $fw400; + &:hover { + color: $color-black; + text-decoration: none; + } + } + + &.active { + a { + color: $color-black; + border-color: $color-primary; + } + } + } + } + + .dashboard-title { + display: flex; + align-items: center; + margin-left: 13px; + + h1 { + color: $color-black; + display: flex; + flex-shrink: 0; + font-size: $fs22; + font-weight: $fw600; + z-index: 10; + user-select: all; + } + + .context-menu.is-open { + margin-top: 10px; + } + } + + .icon { + display: flex; + align-items: center; + cursor: pointer; + margin-left: $size-2; + z-index: 10; + + svg { + fill: $color-gray-40; + width: 15px; + height: 15px; + + &:hover { + fill: $color-primary-dark; + } + } + } + + .dashboard-buttons { + display: flex; + justify-content: flex-end; + align-items: center; + } + + .dashboard-header-actions { + display: flex; + } + + .pin-icon { + margin: 0 $size-2 0 $size-5; + background-color: transparent; + border: none; + svg { + fill: $color-gray-20; + } + + &.active { + svg { + fill: $color-gray-50; + } + } + } +} + +.dashboard-header { + background-color: transparent; + .dashboard-title { + h1 { + color: $df-primary; + font-size: 24px; + font-weight: 400; + width: 100%; + text-overflow: ellipsis; + overflow: hidden; + white-space: nowrap; + display: block; + max-width: 700px; + } + } + .icon { + svg { + fill: $df-secondary; + } + } + + // Settings sub-menu + .dashboard-header-options { + li { + a { + font-size: 16px; + color: $df-secondary; + border-color: transparent; + &:hover { + color: $df-primary; + } + } + &.active { + a { + color: $df-primary; + } + } + } + } +} + +.btn-secondary { + background-color: $db-tertiary; + text-transform: uppercase; + border: none; + color: $df-primary; + border-radius: 8px; + + font-size: 0.75rem; + padding: 0 1rem; + cursor: pointer; + display: flex; + justify-content: center; + align-items: center; + + &:hover { + background-color: $db-cuaternary; + color: $da-primary; + svg { + fill: $da-primary; + } + } +} diff --git a/frontend/src/app/main/ui/dashboard/fonts.cljs b/frontend/src/app/main/ui/dashboard/fonts.cljs index f7236a88ca..e8551a5aed 100644 --- a/frontend/src/app/main/ui/dashboard/fonts.cljs +++ b/frontend/src/app/main/ui/dashboard/fonts.cljs @@ -5,6 +5,7 @@ ;; Copyright (c) KALEIDOS INC (ns app.main.ui.dashboard.fonts + (:require-macros [app.main.style :as stl]) (:require [app.common.media :as cm] [app.main.data.fonts :as df] @@ -14,6 +15,7 @@ [app.main.store :as st] [app.main.ui.components.context-menu :refer [context-menu]] [app.main.ui.components.file-uploader :refer [file-uploader]] + [app.main.ui.context :as ctx] [app.main.ui.icons :as i] [app.util.dom :as dom] [app.util.i18n :as i18n :refer [tr]] @@ -38,29 +40,17 @@ (mf/defc header {::mf/wrap [mf/memo]} [{:keys [section team] :as props}] - ;; (let [go-fonts - ;; (mf/use-callback - ;; (mf/deps team) - ;; #(st/emit! (rt/nav :dashboard-fonts {:team-id (:id team)}))) + (let [new-css-system (mf/use-ctx ctx/new-css-system)] + (use-set-page-title team section) + (if new-css-system + [:header {:class (stl/css :dashboard-header)} + [:div#dashboard-fonts-title {:class (stl/css :dashboard-title)} + [:h1 (tr "labels.fonts")]]] - ;; go-providers - ;; (mf/use-callback - ;; (mf/deps team) - ;; #(st/emit! (rt/nav :dashboard-font-providers {:team-id (:id team)})))] - - (use-set-page-title team section) - - [:header.dashboard-header - [:div.dashboard-title#dashboard-fonts-title - [:h1 (tr "labels.fonts")]] - [:nav - #_[:ul - [:li {:class (when (= section :fonts) "active")} - [:a {:on-click go-fonts} (tr "labels.custom-fonts")]] - [:li {:class (when (= section :providers) "active")} - [:a {:on-click go-providers} (tr "labels.font-providers")]]]] - - [:div]]) + ;; OLD + [:header.dashboard-header + [:div.dashboard-title#dashboard-fonts-title + [:h1 (tr "labels.fonts")]]]))) (mf/defc font-variant-display-name [{:keys [variant]}] @@ -71,7 +61,8 @@ (mf/defc fonts-upload [{:keys [team installed-fonts] :as props}] - (let [fonts (mf/use-state {}) + (let [new-css-system (mf/use-ctx ctx/new-css-system) + fonts (mf/use-state {}) input-ref (mf/use-ref) uploading (mf/use-state #{}) @@ -124,76 +115,151 @@ problematic-fonts? (some :height-warning? (vals @fonts))] - [:div.dashboard-fonts-upload - [:div.dashboard-fonts-hero - [:div.desc - [:h2 (tr "labels.upload-custom-fonts")] - [:& i18n/tr-html {:label "dashboard.fonts.hero-text1"}] + (if new-css-system + [:div {:class (stl/css :dashboard-fonts-upload)} + [:div {:class (stl/css :dashboard-fonts-hero)} + [:div {:class (stl/css :desc)} + [:h2 (tr "labels.upload-custom-fonts")] + [:& i18n/tr-html {:label "dashboard.fonts.hero-text1"}] - [:div.banner - [:div.icon i/msg-info] - [:div.content - [:& i18n/tr-html {:tag-name "span" - :label "dashboard.fonts.hero-text2"}]]] + [:div {:class (stl/css :banner)} + [:div {:class (stl/css :icon)} i/msg-info] + [:div {:class (stl/css :content)} + [:& i18n/tr-html {:tag-name "span" + :label "dashboard.fonts.hero-text2"}]]] - (when problematic-fonts? - [:div.banner.warning - [:div.icon i/msg-warning] + (when problematic-fonts? + [:div {:class (stl/css :banner :warning)} + [:div {:class (stl/css :icon)} i/msg-warning] + [:div {:class (stl/css :content)} + [:& i18n/tr-html {:tag-name "span" + :label "dashboard.fonts.warning-text"}]]])] + + [:button + {:class (stl/css :btn-primary) + :on-click on-click + :tab-index "0"} + [:span (tr "labels.add-custom-font")] + [:& file-uploader {:input-id "font-upload" + :accept cm/str-font-types + :multi true + :ref input-ref + :on-selected on-selected}]]] + + [:* + (when (some? (vals @fonts)) + [:div {:class (stl/css :font-item :table-row)} + [:span (tr "dashboard.fonts.fonts-added" (i18n/c (count (vals @fonts))))] + [:div {:class (stl/css :table-field :options)} + [:div {:class (stl/css :btn-primary) + :on-click #(on-upload-all (vals @fonts)) :data-test "upload-all"} + [:span (tr "dashboard.fonts.upload-all")]] + [:div {:class (stl/css :btn-secondary) + :on-click #(on-dismiss-all (vals @fonts)) :data-test "dismiss-all"} + [:span (tr "dashboard.fonts.dismiss-all")]]]]) + + (for [item (sort-by :font-family (vals @fonts))] + (let [uploading? (contains? @uploading (:id item))] + [:div {:class (stl/css :font-item :table-row) :key (:id item)} + [:div {:class (stl/css :table-field :family)} + [:input {:type "text" + :on-blur #(on-blur-name (:id item) %) + :default-value (:font-family item)}]] + [:div {:class (stl/css :table-field :variants)} + [:span {:class (stl/css :label)} + [:& font-variant-display-name {:variant item}]]] + + [:div {:class (stl/css :table-field :filenames)} + (for [item (:names item)] + [:span item])] + + [:div {:class (stl/css :table-field :options)} + (when (:height-warning? item) + [:span {:class (stl/css :icon :failure)} i/msg-warning]) + + [:button + {:on-click #(on-upload item) + :class (stl/css-case :btn-primary true + :upload-button true + :disabled uploading?) + :disabled uploading?} + (if uploading? + (tr "labels.uploading") + (tr "labels.upload"))] + [:span {:class (stl/css :icon :close) + :on-click #(on-delete item)} i/close]]]))]] + ;; OLD + [:div.dashboard-fonts-upload + [:div.dashboard-fonts-hero + [:div.desc + [:h2 (tr "labels.upload-custom-fonts")] + [:& i18n/tr-html {:label "dashboard.fonts.hero-text1"}] + + [:div.banner + [:div.icon i/msg-info] [:div.content [:& i18n/tr-html {:tag-name "span" - :label "dashboard.fonts.warning-text"}]]])] + :label "dashboard.fonts.hero-text2"}]]] - [:button.btn-primary - {:on-click on-click - :tab-index "0"} - [:span (tr "labels.add-custom-font")] - [:& file-uploader {:input-id "font-upload" - :accept cm/str-font-types - :multi true - :ref input-ref - :on-selected on-selected}]]] + (when problematic-fonts? + [:div.banner.warning + [:div.icon i/msg-warning] + [:div.content + [:& i18n/tr-html {:tag-name "span" + :label "dashboard.fonts.warning-text"}]]])] - [:* - (when (some? (vals @fonts)) - [:div.font-item.table-row - [:span (tr "dashboard.fonts.fonts-added" (i18n/c (count (vals @fonts))))] - [:div.table-field.options - [:div.btn-primary - {:on-click #(on-upload-all (vals @fonts)) :data-test "upload-all"} - [:span (tr "dashboard.fonts.upload-all")]] - [:div.btn-secondary - {:on-click #(on-dismiss-all (vals @fonts)) :data-test "dismiss-all"} - [:span (tr "dashboard.fonts.dismiss-all")]]]]) - - (for [item (sort-by :font-family (vals @fonts))] - (let [uploading? (contains? @uploading (:id item))] - [:div.font-item.table-row {:key (:id item)} - [:div.table-field.family - [:input {:type "text" - :on-blur #(on-blur-name (:id item) %) - :default-value (:font-family item)}]] - [:div.table-field.variants - [:span.label - [:& font-variant-display-name {:variant item}]]] - [:div.table-field.filenames - (for [item (:names item)] - [:span item])] + [:button.btn-primary + {:on-click on-click + :tab-index "0"} + [:span (tr "labels.add-custom-font")] + [:& file-uploader {:input-id "font-upload" + :accept cm/str-font-types + :multi true + :ref input-ref + :on-selected on-selected}]]] + [:* + (when (some? (vals @fonts)) + [:div.font-item.table-row + [:span (tr "dashboard.fonts.fonts-added" (i18n/c (count (vals @fonts))))] [:div.table-field.options - (when (:height-warning? item) - [:span.icon.failure i/msg-warning]) - [:button.btn-primary.upload-button - {:on-click #(on-upload item) - :class (dom/classnames :disabled uploading?) - :disabled uploading?} - (if uploading? - (tr "labels.uploading") - (tr "labels.upload"))] - [:span.icon.close {:on-click #(on-delete item)} i/close]]]))]])) + [:div.btn-primary + {:on-click #(on-upload-all (vals @fonts)) :data-test "upload-all"} + [:span (tr "dashboard.fonts.upload-all")]] + [:div.btn-secondary + {:on-click #(on-dismiss-all (vals @fonts)) :data-test "dismiss-all"} + [:span (tr "dashboard.fonts.dismiss-all")]]]]) + + (for [item (sort-by :font-family (vals @fonts))] + (let [uploading? (contains? @uploading (:id item))] + [:div.font-item.table-row {:key (:id item)} + [:div.table-field.family + [:input {:type "text" + :on-blur #(on-blur-name (:id item) %) + :default-value (:font-family item)}]] + [:div.table-field.variants + [:span.label + [:& font-variant-display-name {:variant item}]]] + [:div.table-field.filenames + (for [item (:names item)] + [:span item])] + + [:div.table-field.options + (when (:height-warning? item) + [:span.icon.failure i/msg-warning]) + [:button.btn-primary.upload-button + {:on-click #(on-upload item) + :class (dom/classnames :disabled uploading?) + :disabled uploading?} + (if uploading? + (tr "labels.uploading") + (tr "labels.upload"))] + [:span.icon.close {:on-click #(on-delete item)} i/close]]]))]]))) (mf/defc installed-font [{:keys [font-id variants] :as props}] - (let [font (first variants) + (let [new-css-system (mf/use-ctx ctx/new-css-system) + font (first variants) variants (sort-by (fn [item] [(:font-weight item) @@ -252,50 +318,97 @@ :on-accept (fn [_props] (delete-variant-fn id))})))] - [:div.font-item.table-row - [:div.table-field.family - (if @edit? - [:input {:type "text" - :default-value @state - :on-key-down on-key-down - :on-change on-change}] - [:span (:font-family font)])] + (if new-css-system + [:div {:class (stl/css :font-item :table-row)} + [:div {:class (stl/css :table-field :family)} + (if @edit? + [:input {:type "text" + :default-value @state + :on-key-down on-key-down + :on-change on-change}] + [:span (:font-family font)])] - [:div.table-field.variants - (for [item variants] - [:div.variant - [:span.label - [:& font-variant-display-name {:variant item}]] - [:span.icon.close - {:on-click #(on-delete-variant (:id item))} - i/plus]])] + [:div {:class (stl/css :table-field :variants)} + (for [item variants] + [:div {:class (stl/css :variant)} + [:span {:class (stl/css :label)} + [:& font-variant-display-name {:variant item}]] + [:span + {:class (stl/css :icon :close) + :on-click #(on-delete-variant (:id item))} + i/plus]])] - [:div] + [:div] - (if @edit? - [:div.table-field.options - [:button.btn-primary - {:disabled (str/blank? @state) - :on-click on-save - :class (dom/classnames :btn-disabled (str/blank? @state))} - (tr "labels.save")] - [:span.icon.close {:on-click on-cancel} i/close]] + (if @edit? + [:div {:class (stl/css :table-field :options)} + [:button + { + :disabled (str/blank? @state) + :on-click on-save + :class (stl/css-case :btn-primary true + :btn-disabled (str/blank? @state))} + (tr "labels.save")] + [:span {:class (stl/css :icon :close) + :on-click on-cancel} i/close]] - [:div.table-field.options - [:span.icon {:on-click #(reset! open-menu? true)} i/actions] - [:& context-menu - {:on-close #(reset! open-menu? false) - :show @open-menu? - :fixed? false - :top -15 - :left -115 - :options [[(tr "labels.edit") #(reset! edit? true) nil "font-edit"] - [(tr "labels.delete") on-delete nil "font-delete"]]}]])])) + [:div {:class (stl/css :table-field :options)} + [:span {:class (stl/css :icon) + :on-click #(reset! open-menu? true)} i/actions] + [:& context-menu + {:on-close #(reset! open-menu? false) + :show @open-menu? + :fixed? false + :top -15 + :left -115 + :options [[(tr "labels.edit") #(reset! edit? true) nil "font-edit"] + [(tr "labels.delete") on-delete nil "font-delete"]]}]])] + ;;OLD + [:div.font-item.table-row + [:div.table-field.family + (if @edit? + [:input {:type "text" + :default-value @state + :on-key-down on-key-down + :on-change on-change}] + [:span (:font-family font)])] + + [:div.table-field.variants + (for [item variants] + [:div.variant + [:span.label + [:& font-variant-display-name {:variant item}]] + [:span.icon.close + {:on-click #(on-delete-variant (:id item))} + i/plus]])] + + [:div] + + (if @edit? + [:div.table-field.options + [:button.btn-primary + {:disabled (str/blank? @state) + :on-click on-save + :class (dom/classnames :btn-disabled (str/blank? @state))} + (tr "labels.save")] + [:span.icon.close {:on-click on-cancel} i/close]] + + [:div.table-field.options + [:span.icon {:on-click #(reset! open-menu? true)} i/actions] + [:& context-menu + {:on-close #(reset! open-menu? false) + :show @open-menu? + :fixed? false + :top -15 + :left -115 + :options [[(tr "labels.edit") #(reset! edit? true) nil "font-edit"] + [(tr "labels.delete") on-delete nil "font-delete"]]}]])]))) (mf/defc installed-fonts [{:keys [fonts] :as props}] - (let [sterm (mf/use-state "") + (let [new-css-system (mf/use-ctx ctx/new-css-system) + sterm (mf/use-state "") matches? #(str/includes? (str/lower (:font-family %)) @sterm) @@ -306,48 +419,99 @@ (let [val (dom/get-target-val event)] (reset! sterm (str/lower val)))))] - [:div.dashboard-installed-fonts - [:h3 (tr "labels.installed-fonts")] - [:div.installed-fonts-header - [:div.table-field.family (tr "labels.font-family")] - [:div.table-field.variants (tr "labels.font-variants")] - [:div] - [:div.table-field.search-input - [:input {:placeholder (tr "labels.search-font") - :default-value "" - :on-change on-change}]]] + (if new-css-system + [:div {:class (stl/css :dashboard-installed-fonts)} + [:h3 (tr "labels.installed-fonts")] + [:div {:class (stl/css :installed-fonts-header)} + [:div {:class (stl/css :table-field :family)} (tr "labels.font-family")] + [:div {:class (stl/css :table-field :variants)} (tr "labels.font-variants")] + [:div] + [:div {:class (stl/css :table-field :search-input)} + [:input {:placeholder (tr "labels.search-font") + :default-value "" + :on-change on-change}]]] - (cond - (seq fonts) - (for [[font-id variants] (->> (vals fonts) - (filter matches?) - (group-by :font-id))] - [:& installed-font {:key (str font-id) - :font-id font-id - :variants variants}]) + (cond + (seq fonts) + (for [[font-id variants] (->> (vals fonts) + (filter matches?) + (group-by :font-id))] + [:& installed-font {:key (str font-id) + :font-id font-id + :variants variants}]) - (nil? fonts) - [:div.fonts-placeholder - [:div.icon i/loader] - [:div.label (tr "dashboard.loading-fonts")]] + (nil? fonts) + [:div {:class (stl/css :fonts-placeholder)} + [:div {:class (stl/css :icon)} i/loader] + [:div {:class (stl/css :label)} (tr "dashboard.loading-fonts")]] - :else - [:div.fonts-placeholder - [:div.icon i/text] - [:div.label (tr "dashboard.fonts.empty-placeholder")]])])) + :else + [:div {:class (stl/css :fonts-placeholder)} + [:div {:class (stl/css :icon)} i/text] + [:div {:class (stl/css :label)} (tr "dashboard.fonts.empty-placeholder")]])] + + ;; OLD + [:div.dashboard-installed-fonts + [:h3 (tr "labels.installed-fonts")] + [:div.installed-fonts-header + [:div.table-field.family (tr "labels.font-family")] + [:div.table-field.variants (tr "labels.font-variants")] + [:div] + [:div.table-field.search-input + [:input {:placeholder (tr "labels.search-font") + :default-value "" + :on-change on-change}]]] + + (cond + (seq fonts) + (for [[font-id variants] (->> (vals fonts) + (filter matches?) + (group-by :font-id))] + [:& installed-font {:key (str font-id) + :font-id font-id + :variants variants}]) + + (nil? fonts) + [:div.fonts-placeholder + [:div.icon i/loader] + [:div.label (tr "dashboard.loading-fonts")]] + + :else + [:div.fonts-placeholder + [:div.icon i/text] + [:div.label (tr "dashboard.fonts.empty-placeholder")]])]))) (mf/defc fonts-page [{:keys [team] :as props}] - (let [fonts (mf/deref refs/dashboard-fonts)] - [:* - [:& header {:team team :section :fonts}] - [:section.dashboard-container.dashboard-fonts - [:& fonts-upload {:team team :installed-fonts fonts}] - [:& installed-fonts {:team team :fonts fonts}]]])) + (let [new-css-system (mf/use-ctx ctx/new-css-system) + fonts (mf/deref refs/dashboard-fonts)] + (if new-css-system + [:* + [:& header {:team team :section :fonts}] + [:section {:class (stl/css :dashboard-container :dashboard-fonts)} + [:& fonts-upload {:team team :installed-fonts fonts}] + [:& installed-fonts {:team team :fonts fonts}]]] + + ;; OLD + [:* + [:& header {:team team :section :fonts}] + [:section.dashboard-container.dashboard-fonts + [:& fonts-upload {:team team :installed-fonts fonts}] + [:& installed-fonts {:team team :fonts fonts}]]]))) (mf/defc font-providers-page [{:keys [team] :as props}] - [:* - [:& header {:team team :section :providers}] - [:section.dashboard-container - [:span "font providers"]]]) + (let [new-css-system (mf/use-ctx ctx/new-css-system)] + (if new-css-system + [:* + [:& header {:team team :section :providers}] + [:section {:class (stl/css :dashboard-container)} + [:span "font providers"]]] + + ;; OLD + [:* + [:& header {:team team :section :providers}] + [:section.dashboard-container + [:span "font providers"]]]))) + + diff --git a/frontend/src/app/main/ui/dashboard/fonts.scss b/frontend/src/app/main/ui/dashboard/fonts.scss new file mode 100644 index 0000000000..5273c0a9b9 --- /dev/null +++ b/frontend/src/app/main/ui/dashboard/fonts.scss @@ -0,0 +1,621 @@ +@import "common/dependencies/colors"; + +$br3: 3px; +$fs12: 0.75rem; +$fs14: 0.875rem; +$fs14: 0.875rem; +$fs18: 1.125rem; +$fs22: 1.375rem; +$fw400: 400; +$fw600: 600; +$lh-088: 0.88; +$lh-115: 1.15; // original $title-lh-sm +$size-1: 0.25rem; +$size-2: 0.5rem; +$size-4: 1rem; +$size-5: 1.5rem; +$size-6: 2rem; + +.dashboard-header { + display: flex; + align-items: center; + justify-content: space-between; + background-color: $color-white; + height: 63px; + padding: $size-1 $size-4 $size-1 $size-2; + position: relative; + z-index: 10; + user-select: none; + &.team { + display: grid; + grid-template-columns: 20% 1fr 20%; + } + + .element-name { + margin-right: $size-2; + } + + .btn-secondary { + flex-shrink: 0; + z-index: 10; + height: 32px; + } + + svg { + fill: $color-black; + height: 14px; + margin-right: $size-1; + width: 14px; + } + + nav { + display: flex; + align-items: flex-end; + justify-content: center; + z-index: 1; + + ul { + display: flex; + font-size: $fs14; + justify-content: center; + margin: 0; + } + + li { + a { + display: flex; + align-items: center; + flex-basis: 140px; + border-bottom: 3px solid transparent; + color: $color-gray-30; + height: 40px; + padding: $size-1 $size-5; + font-weight: $fw400; + &:hover { + color: $color-black; + text-decoration: none; + } + } + + &.active { + a { + color: $color-black; + border-color: $color-primary; + } + } + } + } + + .dashboard-title { + display: flex; + align-items: center; + margin-left: 13px; + + h1 { + color: $color-black; + display: flex; + flex-shrink: 0; + font-size: $fs22; + font-weight: $fw600; + z-index: 10; + user-select: all; + } + + .context-menu.is-open { + margin-top: 10px; + } + } + + .icon { + display: flex; + align-items: center; + cursor: pointer; + margin-left: $size-2; + z-index: 10; + + svg { + fill: $color-gray-40; + width: 15px; + height: 15px; + + &:hover { + fill: $color-primary-dark; + } + } + } + + .dashboard-buttons { + display: flex; + justify-content: flex-end; + align-items: center; + } + + .dashboard-header-actions { + display: flex; + } + + .pin-icon { + margin: 0 $size-2 0 $size-5; + background-color: transparent; + border: none; + svg { + fill: $color-gray-20; + } + + &.active { + svg { + fill: $color-gray-50; + } + } + } +} + +.dashboard-header { + background-color: transparent; + .dashboard-title { + h1 { + color: $df-primary; + font-size: 24px; + font-weight: 400; + width: 100%; + text-overflow: ellipsis; + overflow: hidden; + white-space: nowrap; + display: block; + max-width: 700px; + } + } + .icon { + svg { + fill: $df-secondary; + } + } + + // Settings sub-menu + .dashboard-header-options { + li { + a { + font-size: 16px; + color: $df-secondary; + border-color: transparent; + &:hover { + color: $df-primary; + } + } + &.active { + a { + color: $df-primary; + } + } + } + } +} + +.dashboard-fonts { + display: flex; + flex-direction: column; + align-items: center; + + .dashboard-installed-fonts { + max-width: 1000px; + width: 100%; + display: flex; + margin-top: $size-5; + flex-direction: column; + + h3 { + font-size: $fs14; + color: $color-gray-30; + margin: $size-1; + } + + .font-item { + color: $color-black; + } + } + + .installed-fonts-header { + color: $color-gray-40; + display: flex; + height: 40px; + font-size: $fs12; + background-color: $color-white; + align-items: center; + padding: 0px $size-5; + + > .family { + min-width: 200px; + width: 200px; + } + + > .variants { + padding-left: 12px; + } + + .search-input { + display: flex; + flex-grow: 1; + justify-content: flex-end; + + input { + font-size: $fs12; + border: 1px solid $color-gray-30; + border-radius: $br3; + width: 130px; + padding: $size-1; + margin: 0px; + } + } + } + + .font-item { + color: $color-gray-40; + font-size: $fs14; + background-color: $color-white; + display: flex; + max-width: 1000px; + width: 100%; + min-height: 97px; + align-items: center; + padding: $size-5; + justify-content: space-between; + + &:not(:first-child) { + border-top: 1px solid $color-gray-10; + } + + input { + border: 1px solid $color-gray-30; + border-radius: $br3; + margin: 0px; + padding: $size-2; + font-size: $fs12; + } + + > .family { + min-width: 200px; + width: 200px; + } + + > .filenames { + min-width: 200px; + } + + > .variants { + font-size: $fs14; + display: flex; + flex-wrap: wrap; + flex-grow: 1; + + .variant { + display: flex; + justify-content: space-between; + align-items: center; + padding: 8px 12px; + cursor: pointer; + + .icon { + display: flex; + height: 16px; + width: 16px; + margin-left: 6px; + align-items: center; + svg { + fill: transparent; + width: 12px; + height: 12px; + transform: rotate(45deg); + } + } + + &:hover { + .icon svg { + fill: $color-gray-30; + } + } + } + } + + .filenames { + display: flex; + flex-direction: column; + font-size: $fs12; + } + + .options { + display: flex; + justify-content: flex-end; + min-width: 180px; + + .icon { + width: $size-5; + cursor: pointer; + display: flex; + margin-left: 10px; + justify-content: center; + align-items: center; + &.failure { + margin-right: 10px; + svg { + fill: $color-warning; + } + } + svg { + width: 16px; + height: 16px; + fill: $df-secondary; + } + + &.close { + svg { + transform: rotate(45deg); + fill: $df-secondary; + } + } + } + } + } + + .dashboard-fonts-upload { + max-width: 1000px; + width: 100%; + display: flex; + flex-direction: column; + + .upload-button { + width: 100px; + } + + .btn-secondary { + margin-left: 10px; + } + } + + .dashboard-fonts-hero { + font-size: $fs14; + padding: $size-6; + background-color: $color-white; + margin-top: $size-6; + display: flex; + justify-content: space-between; + + .banner { + background-color: $color-info-lighter; + display: grid; + grid-template-columns: 40px 1fr; + &:not(:last-child) { + margin-bottom: 10px; + } + .icon { + display: flex; + align-items: flex-start; + justify-content: center; + padding-top: 10px; + background-color: $color-info; + svg { + fill: $color-white; + height: 20px; + width: 20px; + } + } + .content { + margin: 10px; + } + &.warning { + background-color: $color-warning-lighter; + .icon { + background-color: $color-warning; + } + } + } + + .desc { + h2 { + margin-bottom: $size-4; + color: $color-black; + } + width: 80%; + color: $color-gray-40; + } + + .btn-primary { + flex-shrink: 0; + } + } + + .fonts-placeholder { + display: flex; + flex-direction: column; + justify-content: center; + align-items: center; + max-width: 1000px; + width: 100%; + height: 161px; + + border: 1px dashed $color-gray-20; + margin-top: 16px; + + .icon { + svg { + fill: $color-gray-40; + width: 32px; + height: 32px; + } + } + + .label { + color: $color-gray-40; + font-size: $fs14; + } + } +} + +.dashboard-fonts { + background-color: $db-primary; + border-top: 1px solid $db-cuaternary; + + .dashboard-fonts-hero { + background-color: transparent; + .desc { + width: 70%; + h2 { + color: $df-primary; + font-weight: 400; + } + p { + color: $df-secondary; + font-size: 14px; + } + .banner { + background-color: $db-primary; + border-radius: 8px; + border: 1px solid $db-cuaternary; + color: $df-primary; + font-size: 12px; + .content { + span { + a { + color: $da-primary; + } + } + } + .icon { + background-color: transparent; + svg { + fill: $df-secondary; + } + } + &.warning { + background-color: $db-cuaternary; + } + } + } + } + + .installed-fonts-header { + background-color: transparent; + text-transform: uppercase; + color: $df-secondary; + } + + .fonts-placeholder { + border: 1px solid $db-cuaternary; + border-radius: 8px; + .icon { + svg { + fill: $df-secondary; + } + } + .label { + color: $df-secondary; + } + } + + .font-item { + background-color: $db-tertiary; + border-radius: 8px; + color: $df-secondary; + padding: 0.8rem 1.5rem; + min-height: auto; + margin-top: 4px; + &:not(:first-child) { + border: none; + } + .table-field { + color: $df-primary; + .variant { + background-color: $db-cuaternary; + border-radius: 8px; + margin-right: 4px; + padding-right: 4px; + } + } + } + + .font-item { + input { + background-color: $db-tertiary; + border-color: transparent; + border-radius: 8px; + color: $df-primary; + font-size: 14px; + &:focus { + outline: 1px solid $da-primary; + } + } + > .variants { + padding-left: 1rem; + } + } + + .installed-fonts-header { + padding-right: 0; + .search-input { + input { + background-color: $db-tertiary; + border-color: transparent; + border-radius: 8px; + color: $df-primary; + font-size: 14px; + height: 32px; + padding: 0 0.6rem; + width: 150px; + &:focus { + outline: 1px solid $da-primary; + } + &::placeholder { + color: $df-secondary; + } + } + } + } +} + +.btn-primary { + background-color: $da-tertiary; + border-radius: 8px; + color: $db-primary; + height: 32px; + text-transform: uppercase; + + appearance: none; + align-items: center; + border: none; + cursor: pointer; + display: flex; + font-family: "worksans", sans-serif; + font-size: $fs12; + justify-content: center; + min-width: 25px; + padding: 0 1rem; + transition: all 0.4s; + text-decoration: none; + + &:hover { + background-color: darken($da-tertiary, 10%); + color: $db-primary; + } +} + +.btn-secondary { + background-color: $db-tertiary; + text-transform: uppercase; + border: none; + color: $df-primary; + border-radius: 8px; + + font-size: 0.75rem; + padding: 0 1rem; + cursor: pointer; + display: flex; + justify-content: center; + align-items: center; + + &:hover { + background-color: $db-cuaternary; + color: $da-primary; + svg { + fill: $da-primary; + } + } +} diff --git a/frontend/src/app/main/ui/dashboard/grid.cljs b/frontend/src/app/main/ui/dashboard/grid.cljs index 4720e0fe21..61b58cf4ef 100644 --- a/frontend/src/app/main/ui/dashboard/grid.cljs +++ b/frontend/src/app/main/ui/dashboard/grid.cljs @@ -5,6 +5,7 @@ ;; Copyright (c) KALEIDOS INC (ns app.main.ui.dashboard.grid + (:require-macros [app.main.style :as stl]) (:require [app.common.data.macros :as dm] [app.common.geom.point :as gpt] @@ -19,6 +20,7 @@ [app.main.repo :as rp] [app.main.store :as st] [app.main.ui.components.color-bullet :as bc] + [app.main.ui.context :as ctx] [app.main.ui.dashboard.file-menu :refer [file-menu]] [app.main.ui.dashboard.import :refer [use-import-file]] [app.main.ui.dashboard.inline-edition :refer [inline-edition]] @@ -66,7 +68,8 @@ (mf/defc grid-item-thumbnail {::mf/wrap-props false} [{:keys [file-id revn thumbnail-uri background-color]}] - (let [container (mf/use-ref) + (let [new-css-system (mf/use-ctx ctx/new-css-system) + container (mf/use-ref) visible? (h/use-visible container :once? true)] (mf/with-effect [file-id revn visible? thumbnail-uri] @@ -80,13 +83,24 @@ :revn revn :message (ex-message cause))))))) - [:div.grid-item-th - {:style {:background-color background-color} - :ref container} - (when visible? - (if thumbnail-uri - [:img.grid-item-thumbnail-image {:src thumbnail-uri}] - i/loader-pencil))])) + (if new-css-system + [:div {:class (stl/css :grid-item-th) + :style {:background-color background-color} + :ref container} + (when visible? + (if thumbnail-uri + [:img {:class (stl/css :grid-item-thumbnail-image) + :src thumbnail-uri}] + i/loader-pencil))] + + ;; OLD + [:div.grid-item-th + {:style {:background-color background-color} + :ref container} + (when visible? + (if thumbnail-uri + [:img.grid-item-thumbnail-image {:src thumbnail-uri}] + i/loader-pencil))]))) ;; --- Grid Item Library @@ -94,108 +108,209 @@ {::mf/wrap [mf/memo]} [{:keys [file] :as props}] - (mf/with-effect [file] - (when file - (let [font-ids (map :font-id (get-in file [:library-summary :typographies :sample] []))] - (run! fonts/ensure-loaded! font-ids)))) + (let [new-css-system (mf/use-ctx ctx/new-css-system)] + (mf/with-effect [file] + (when file + (let [font-ids (map :font-id (get-in file [:library-summary :typographies :sample] []))] + (run! fonts/ensure-loaded! font-ids)))) - [:div.grid-item-th.library - (if (nil? file) - i/loader-pencil - (let [summary (:library-summary file) - components (:components summary) - colors (:colors summary) - typographies (:typographies summary)] - [:* - - (when (and (zero? (:count components)) (zero? (:count colors)) (zero? (:count typographies))) - [:* - [:div.asset-section - [:div.asset-title - [:span (tr "workspace.assets.components")] - [:span.num-assets (str "\u00A0(") 0 ")"]]] ;; Unicode 00A0 is non-breaking space - [:div.asset-section - [:div.asset-title - [:span (tr "workspace.assets.colors")] - [:span.num-assets (str "\u00A0(") 0 ")"]]] ;; Unicode 00A0 is non-breaking space - [:div.asset-section - [:div.asset-title - [:span (tr "workspace.assets.typography")] - [:span.num-assets (str "\u00A0(") 0 ")"]]]]) ;; Unicode 00A0 is non-breaking space + (if new-css-system + [:div {:class (stl/css :grid-item-th :library)} + (if (nil? file) + i/loader-pencil + (let [summary (:library-summary file) + components (:components summary) + colors (:colors summary) + typographies (:typographies summary)] + [:* + (when (and (zero? (:count components)) (zero? (:count colors)) (zero? (:count typographies))) + [:* + [:div {:class (stl/css :asset-section)} + [:div {:class (stl/css :asset-title)} + [:span (tr "workspace.assets.components")] + [:span {:class (stl/css :num-assets)} (str "\u00A0(") 0 ")"]]] ;; Unicode 00A0 is non-breaking space + [:div {:class (stl/css :asset-section)} + [:div {:class (stl/css :asset-title)} + [:span (tr "workspace.assets.colors")] + [:span {:class (stl/css :num-assets)} (str "\u00A0(") 0 ")"]]] ;; Unicode 00A0 is non-breaking space + [:div {:class (stl/css :asset-section)} + [:div {:class (stl/css :asset-title)} + [:span (tr "workspace.assets.typography")] + [:span {:class (stl/css :num-assets)} (str "\u00A0(") 0 ")"]]]]) ;; Unicode 00A0 is non-breaking space - (when (pos? (:count components)) - [:div.asset-section - [:div.asset-title - [:span (tr "workspace.assets.components")] - [:span.num-assets (str "\u00A0(") (:count components) ")"]] ;; Unicode 00A0 is non-breaking space - [:div.asset-list - (for [component (:sample components)] - (let [root-id (or (:main-instance-id component) (:id component))] ;; Check for components-v2 in library - [:div.asset-list-item {:key (str "assets-component-" (:id component))} - [:& component-svg {:root-shape (get-in component [:objects root-id]) - :objects (:objects component)}] ;; Components in the summary come loaded with objects, even in v2 - [:div.name-block - [:span.item-name {:title (:name component)} - (:name component)]]])) - (when (> (:count components) (count (:sample components))) - [:div.asset-list-item - [:div.name-block - [:span.item-name "(...)"]]])]]) + (when (pos? (:count components)) + [:div {:class (stl/css :asset-section)} + [:div {:class (stl/css :asset-title)} + [:span (tr "workspace.assets.components")] + [:span {:class (stl/css :num-assets)} (str "\u00A0(") (:count components) ")"]] ;; Unicode 00A0 is non-breaking space + [:div {:class (stl/css :asset-list)} + (for [component (:sample components)] + (let [root-id (or (:main-instance-id component) (:id component))] ;; Check for components-v2 in library + [:div {:class (stl/css :asset-list-item) + :key (str "assets-component-" (:id component))} + [:& component-svg {:root-shape (get-in component [:objects root-id]) + :objects (:objects component)}] ;; Components in the summary come loaded with objects, even in v2 + [:div {:class (stl/css :name-block)} + [:span {:class (stl/css :item-name) + :title (:name component)} + (:name component)]]])) + (when (> (:count components) (count (:sample components))) + [:div {:class (stl/css :asset-list-item)} + [:div {:class (stl/css :name-block)} + [:span {:class (stl/css :item-name)} "(...)"]]])]]) - (when (pos? (:count colors)) - [:div.asset-section - [:div.asset-title - [:span (tr "workspace.assets.colors")] - [:span.num-assets (str "\u00A0(") (:count colors) ")"]] ;; Unicode 00A0 is non-breaking space - [:div.asset-list - (for [color (:sample colors)] - (let [default-name (cond - (:gradient color) (uc/gradient-type->string (get-in color [:gradient :type])) - (:color color) (:color color) - :else (:value color))] - [:div.asset-list-item {:key (str "assets-color-" (:id color))} - [:& bc/color-bullet {:color {:color (:color color) - :opacity (:opacity color)}}] - [:div.name-block - [:span.color-name (:name color)] - (when-not (= (:name color) default-name) - [:span.color-value (:color color)])]])) - (when (> (:count colors) (count (:sample colors))) - [:div.asset-list-item - [:div.name-block - [:span.item-name "(...)"]]])]]) + (when (pos? (:count colors)) + [:div {:class (stl/css :asset-section)} + [:div {:class (stl/css :asset-title)} + [:span (tr "workspace.assets.colors")] + [:span {:class (stl/css :num-assets)} (str "\u00A0(") (:count colors) ")"]] ;; Unicode 00A0 is non-breaking space + [:div {:class (stl/css :asset-list)} + (for [color (:sample colors)] + (let [default-name (cond + (:gradient color) (uc/gradient-type->string (get-in color [:gradient :type])) + (:color color) (:color color) + :else (:value color))] + [:div {:class (stl/css :asset-list-item) + :key (str "assets-color-" (:id color))} + [:& bc/color-bullet {:color {:color (:color color) + :opacity (:opacity color)}}] + [:div {:class (stl/css :name-block)} + [:span {:class (stl/css :color-name)} (:name color)] + (when-not (= (:name color) default-name) + [:span {:class (stl/css :color-value)} (:color color)])]])) - (when (pos? (:count typographies)) - [:div.asset-section - [:div.asset-title - [:span (tr "workspace.assets.typography")] - [:span.num-assets (str "\u00A0(") (:count typographies) ")"]] ;; Unicode 00A0 is non-breaking space - [:div.asset-list - (for [typography (:sample typographies)] - [:div.asset-list-item {:key (str "assets-typography-" (:id typography))} - [:div.typography-sample - {:style {:font-family (:font-family typography) - :font-weight (:font-weight typography) - :font-style (:font-style typography)}} - (tr "workspace.assets.typography.sample")] - [:div.name-block - [:span.item-name {:title (:name typography)} - (:name typography)]]]) - (when (> (:count typographies) (count (:sample typographies))) - [:div.asset-list-item - [:div.name-block - [:span.item-name "(...)"]]])]])]))]) + (when (> (:count colors) (count (:sample colors))) + [:div {:class (stl/css :asset-list-item)} + [:div {:class (stl/css :name-block)} + [:span {:class (stl/css :item-name)} "(...)"]]])]]) + + (when (pos? (:count typographies)) + [:div {:class (stl/css :asset-section)} + [:div {:class (stl/css :asset-title)} + [:span (tr "workspace.assets.typography")] + [:span {:class (stl/css :num-assets)} (str "\u00A0(") (:count typographies) ")"]] ;; Unicode 00A0 is non-breaking space + [:div {:class (stl/css :asset-list)} + (for [typography (:sample typographies)] + [:div {:class (stl/css :asset-list-item) + :key (str "assets-typography-" (:id typography))} + [:div {:class (stl/css :typography-sample) + :style {:font-family (:font-family typography) + :font-weight (:font-weight typography) + :font-style (:font-style typography)}} + (tr "workspace.assets.typography.sample")] + [:div {:class (stl/css :name-block)} + [:span {:class (stl/css :item-name) + :title (:name typography)} + (:name typography)]]]) + + (when (> (:count typographies) (count (:sample typographies))) + [:div {:class (stl/css :asset-list-item)} + [:div {:class (stl/css :name-block)} + [:span {:class (stl/css :item-name)} "(...)"]]])]])]))] + + ;; OLD + [:div.grid-item-th.library + (if (nil? file) + i/loader-pencil + (let [summary (:library-summary file) + components (:components summary) + colors (:colors summary) + typographies (:typographies summary)] + [:* + + (when (and (zero? (:count components)) (zero? (:count colors)) (zero? (:count typographies))) + [:* + [:div.asset-section + [:div.asset-title + [:span (tr "workspace.assets.components")] + [:span.num-assets (str "\u00A0(") 0 ")"]]] ;; Unicode 00A0 is non-breaking space + [:div.asset-section + [:div.asset-title + [:span (tr "workspace.assets.colors")] + [:span.num-assets (str "\u00A0(") 0 ")"]]] ;; Unicode 00A0 is non-breaking space + [:div.asset-section + [:div.asset-title + [:span (tr "workspace.assets.typography")] + [:span.num-assets (str "\u00A0(") 0 ")"]]]]) ;; Unicode 00A0 is non-breaking space + + + (when (pos? (:count components)) + [:div.asset-section + [:div.asset-title + [:span (tr "workspace.assets.components")] + [:span.num-assets (str "\u00A0(") (:count components) ")"]] ;; Unicode 00A0 is non-breaking space + [:div.asset-list + (for [component (:sample components)] + (let [root-id (or (:main-instance-id component) (:id component))] ;; Check for components-v2 in library + [:div.asset-list-item {:key (str "assets-component-" (:id component))} + [:& component-svg {:root-shape (get-in component [:objects root-id]) + :objects (:objects component)}] ;; Components in the summary come loaded with objects, even in v2 + [:div.name-block + [:span.item-name {:title (:name component)} + (:name component)]]])) + (when (> (:count components) (count (:sample components))) + [:div.asset-list-item + [:div.name-block + [:span.item-name "(...)"]]])]]) + + (when (pos? (:count colors)) + [:div.asset-section + [:div.asset-title + [:span (tr "workspace.assets.colors")] + [:span.num-assets (str "\u00A0(") (:count colors) ")"]] ;; Unicode 00A0 is non-breaking space + [:div.asset-list + (for [color (:sample colors)] + (let [default-name (cond + (:gradient color) (uc/gradient-type->string (get-in color [:gradient :type])) + (:color color) (:color color) + :else (:value color))] + [:div.asset-list-item {:key (str "assets-color-" (:id color))} + [:& bc/color-bullet {:color {:color (:color color) + :opacity (:opacity color)}}] + [:div.name-block + [:span.color-name (:name color)] + (when-not (= (:name color) default-name) + [:span.color-value (:color color)])]])) + (when (> (:count colors) (count (:sample colors))) + [:div.asset-list-item + [:div.name-block + [:span.item-name "(...)"]]])]]) + + (when (pos? (:count typographies)) + [:div.asset-section + [:div.asset-title + [:span (tr "workspace.assets.typography")] + [:span.num-assets (str "\u00A0(") (:count typographies) ")"]] ;; Unicode 00A0 is non-breaking space + [:div.asset-list + (for [typography (:sample typographies)] + [:div.asset-list-item {:key (str "assets-typography-" (:id typography))} + [:div.typography-sample + {:style {:font-family (:font-family typography) + :font-weight (:font-weight typography) + :font-style (:font-style typography)}} + (tr "workspace.assets.typography.sample")] + [:div.name-block + [:span.item-name {:title (:name typography)} + (:name typography)]]]) + (when (> (:count typographies) (count (:sample typographies))) + [:div.asset-list-item + [:div.name-block + [:span.item-name "(...)"]]])]])]))]))) ;; --- Grid Item (mf/defc grid-item-metadata [{:keys [modified-at]}] - (let [locale (mf/deref i18n/locale) + (let [new-css-system (mf/use-ctx ctx/new-css-system) + locale (mf/deref i18n/locale) time (dt/timeago modified-at {:locale locale})] - [:span.date - time])) + (if new-css-system + [:span {:class (stl/css :date)} time] + + ;; OLD + [:span.date time]))) (defn create-counter-element [_element file-count] @@ -207,7 +322,8 @@ (mf/defc grid-item {:wrap [mf/memo]} [{:keys [file navigate? origin library-view?] :as props}] - (let [file-id (:id file) + (let [new-css-system (mf/use-ctx ctx/new-css-system) + file-id (:id file) local (mf/use-state {:menu-open false :menu-pos nil :edition false}) @@ -313,71 +429,139 @@ (when (and (not selected?) (:menu-open @local)) (swap! local assoc :menu-open false))) - [:li.grid-item.project-th {:class (dom/classnames :library library-view?)} - [:button - {:tab-index "0" - :class (dom/classnames :selected selected? - :library library-view?) - :ref node-ref - :draggable true - :on-click on-select - :on-key-down (fn [event] - (dom/stop-propagation event) - (when (kbd/enter? event) - (on-navigate event)) - (when (kbd/shift? event) - (when (or (kbd/down-arrow? event) (kbd/left-arrow? event) (kbd/up-arrow? event) (kbd/right-arrow? event)) - (on-select event)) ;; TODO Fix this - )) - :on-double-click on-navigate - :on-drag-start on-drag-start - :on-context-menu on-menu-click} + (if new-css-system + [:li + {:class (stl/css-case :grid-item true :project-th true :library library-view?)} + [:button + {:tab-index "0" + :class (stl/css-case :selected selected? :library library-view?) + :ref node-ref + :draggable true + :on-click on-select + :on-key-down (fn [event] + (dom/stop-propagation event) + (when (kbd/enter? event) + (on-navigate event)) + (when (kbd/shift? event) + (when (or (kbd/down-arrow? event) (kbd/left-arrow? event) (kbd/up-arrow? event) (kbd/right-arrow? event)) + (on-select event)) ;; TODO Fix this + )) + :on-double-click on-navigate + :on-drag-start on-drag-start + :on-context-menu on-menu-click} - [:div.overlay] - (if library-view? - [:& grid-item-library {:file file}] - [:& grid-item-thumbnail - {:file-id (:id file) - :revn (:revn file) - :thumbnail-uri (:thumbnail-uri file) - :background-color (dm/get-in file [:data :options :background])}]) + [:div {:class (stl/css :overlay)}] - (when (and (:is-shared file) (not library-view?)) - [:div.item-badge i/library]) - [:div.info-wrapper - [:div.item-info - (if (:edition @local) - [:& inline-edition {:content (:name file) - :on-end edit}] - [:h3 (:name file)]) - [:& grid-item-metadata {:modified-at (:modified-at file)}]] - [:div.project-th-actions {:class (dom/classnames - :force-display (:menu-open @local))} - [:div.project-th-icon.menu - {:tab-index "0" - :ref menu-ref - :id (str file-id "-action-menu") - :on-click on-menu-click - :on-key-down (fn [event] - (when (kbd/enter? event) - (dom/stop-propagation event) - (on-menu-click event)))} - i/actions - (when selected? - [:& file-menu {:files (vals selected-files) - :show? (:menu-open @local) - :left (+ 24 (:x (:menu-pos @local))) - :top (:y (:menu-pos @local)) - :navigate? navigate? - :on-edit on-edit - :on-menu-close on-menu-close - :origin origin - :dashboard-local dashboard-local - :parent-id (str file-id "-action-menu")}])]]]]])) + (if library-view? + [:& grid-item-library {:file file}] + [:& grid-item-thumbnail + {:file-id (:id file) + :revn (:revn file) + :thumbnail-uri (:thumbnail-uri file) + :background-color (dm/get-in file [:data :options :background])}]) + + (when (and (:is-shared file) (not library-view?)) + [:div {:class (stl/css :item-badge)} i/library]) + + [:div {:class (stl/css :info-wrapper)} + [:div {:class (stl/css :item-info)} + (if (:edition @local) + [:& inline-edition {:content (:name file) + :on-end edit}] + [:h3 (:name file)]) + [:& grid-item-metadata {:modified-at (:modified-at file)}]] + + [:div {:class (stl/css-case :project-th-actions true :force-display (:menu-open @local))} + [:div + {:class (stl/css :project-th-icon :menu) + :tab-index "0" + :ref menu-ref + :id (str file-id "-action-menu") + :on-click on-menu-click + :on-key-down (fn [event] + (when (kbd/enter? event) + (dom/stop-propagation event) + (on-menu-click event)))} + i/actions + (when selected? + [:& file-menu {:files (vals selected-files) + :show? (:menu-open @local) + :left (+ 24 (:x (:menu-pos @local))) + :top (:y (:menu-pos @local)) + :navigate? navigate? + :on-edit on-edit + :on-menu-close on-menu-close + :origin origin + :dashboard-local dashboard-local + :parent-id (str file-id "-action-menu")}])]]]]] + + ;; OLD + [:li.grid-item.project-th {:class (dom/classnames :library library-view?)} + [:button + {:tab-index "0" + :class (dom/classnames :selected selected? + :library library-view?) + :ref node-ref + :draggable true + :on-click on-select + :on-key-down (fn [event] + (dom/stop-propagation event) + (when (kbd/enter? event) + (on-navigate event)) + (when (kbd/shift? event) + (when (or (kbd/down-arrow? event) (kbd/left-arrow? event) (kbd/up-arrow? event) (kbd/right-arrow? event)) + (on-select event)) ;; TODO Fix this + )) + :on-double-click on-navigate + :on-drag-start on-drag-start + :on-context-menu on-menu-click} + + [:div.overlay] + (if library-view? + [:& grid-item-library {:file file}] + [:& grid-item-thumbnail + {:file-id (:id file) + :revn (:revn file) + :thumbnail-uri (:thumbnail-uri file) + :background-color (dm/get-in file [:data :options :background])}]) + + (when (and (:is-shared file) (not library-view?)) + [:div.item-badge i/library]) + [:div.info-wrapper + [:div.item-info + (if (:edition @local) + [:& inline-edition {:content (:name file) + :on-end edit}] + [:h3 (:name file)]) + [:& grid-item-metadata {:modified-at (:modified-at file)}]] + [:div.project-th-actions {:class (dom/classnames + :force-display (:menu-open @local))} + [:div.project-th-icon.menu + {:tab-index "0" + :ref menu-ref + :id (str file-id "-action-menu") + :on-click on-menu-click + :on-key-down (fn [event] + (when (kbd/enter? event) + (dom/stop-propagation event) + (on-menu-click event)))} + i/actions + (when selected? + [:& file-menu {:files (vals selected-files) + :show? (:menu-open @local) + :left (+ 24 (:x (:menu-pos @local))) + :top (:y (:menu-pos @local)) + :navigate? navigate? + :on-edit on-edit + :on-menu-close on-menu-close + :origin origin + :dashboard-local dashboard-local + :parent-id (str file-id "-action-menu")}])]]]]]))) (mf/defc grid [{:keys [files project origin limit library-view? create-fn] :as props}] - (let [dragging? (mf/use-state false) + (let [new-css-system (mf/use-ctx ctx/new-css-system) + dragging? (mf/use-state false) project-id (:id project) node-ref (mf/use-var nil) @@ -420,57 +604,112 @@ (reset! dragging? false) (import-files (.-files (.-dataTransfer e))))))] - [:div.dashboard-grid - {:on-drag-enter on-drag-enter - :on-drag-over on-drag-over - :on-drag-leave on-drag-leave - :on-drop on-drop - :ref node-ref} - (cond - (nil? files) - [:& loading-placeholder] + (if new-css-system + [:div + {:class (stl/css :dashboard-grid) + :on-drag-enter on-drag-enter + :on-drag-over on-drag-over + :on-drag-leave on-drag-leave + :on-drop on-drop + :ref node-ref} - (seq files) - [:ul.grid-row - {:style {:grid-template-columns (str "repeat(" limit ", 1fr)")}} + (cond + (nil? files) + [:& loading-placeholder] - (when @dragging? - [:li.grid-item]) + (seq files) + [:ul + {:class (stl/css :grid-row) + :style {:grid-template-columns (str "repeat(" limit ", 1fr)")}} - (for [item files] - [:& grid-item - {:file item - :key (:id item) - :navigate? true - :origin origin - :library-view? library-view?}])] + (when @dragging? + [:li {:class (stl/css :grid-item)}]) - :else - [:& empty-placeholder - {:limit limit - :create-fn create-fn - :origin origin}])])) + (for [item files] + [:& grid-item + {:file item + :key (:id item) + :navigate? true + :origin origin + :library-view? library-view?}])] + + :else + [:& empty-placeholder + {:limit limit + :create-fn create-fn + :origin origin}])] + + ;; OLD + [:div.dashboard-grid + {:on-drag-enter on-drag-enter + :on-drag-over on-drag-over + :on-drag-leave on-drag-leave + :on-drop on-drop + :ref node-ref} + (cond + (nil? files) + [:& loading-placeholder] + + (seq files) + [:ul.grid-row + {:style {:grid-template-columns (str "repeat(" limit ", 1fr)")}} + + (when @dragging? + [:li.grid-item]) + + (for [item files] + [:& grid-item + {:file item + :key (:id item) + :navigate? true + :origin origin + :library-view? library-view?}])] + + :else + [:& empty-placeholder + {:limit limit + :create-fn create-fn + :origin origin}])]))) (mf/defc line-grid-row [{:keys [files selected-files dragging? limit] :as props}] - (let [elements limit + (let [new-css-system (mf/use-ctx ctx/new-css-system) + elements limit limit (if dragging? (dec limit) limit)] - [:ul.grid-row.no-wrap - {:style {:grid-template-columns (dm/str "repeat(" elements ", 1fr)")}} + (if new-css-system + [:ul + {:class (stl/css :grid-row :no-wrap) + :style {:grid-template-columns (dm/str "repeat(" elements ", 1fr)")}} - (when dragging? - [:li.grid-item.dragged]) - (for [item (take limit files)] - [:& grid-item - {:id (:id item) - :file item - :selected-files selected-files - :key (:id item) - :navigate? false}])])) + (when dragging? + [:li {:class (stl/css :grid-item :dragged)}]) + + (for [item (take limit files)] + [:& grid-item + {:id (:id item) + :file item + :selected-files selected-files + :key (:id item) + :navigate? false}])] + + ;; OLD + [:ul.grid-row.no-wrap + {:style {:grid-template-columns (dm/str "repeat(" elements ", 1fr)")}} + + (when dragging? + [:li.grid-item.dragged]) + (for [item (take limit files)] + [:& grid-item + {:id (:id item) + :file item + :selected-files selected-files + :key (:id item) + :navigate? false}])]))) (mf/defc line-grid [{:keys [project team files limit create-fn] :as props}] - (let [dragging? (mf/use-state false) + (let [new-css-system (mf/use-ctx ctx/new-css-system) + dragging? (mf/use-state false) project-id (:id project) team-id (:id team) @@ -546,24 +785,49 @@ (reset! dragging? false) (import-files (.-files (.-dataTransfer e)))))))] - [:div.dashboard-grid {:on-drag-enter on-drag-enter - :on-drag-over on-drag-over - :on-drag-leave on-drag-leave - :on-drop on-drop} - (cond - (nil? files) - [:& loading-placeholder] + (if new-css-system + [:div {:class (stl/css :dashboard-grid) + :on-drag-enter on-drag-enter + :on-drag-over on-drag-over + :on-drag-leave on-drag-leave + :on-drop on-drop} + (cond + (nil? files) + [:& loading-placeholder] - (seq files) - [:& line-grid-row {:files files - :team-id team-id - :selected-files selected-files - :dragging? @dragging? - :limit limit}] + (seq files) + [:& line-grid-row {:files files + :team-id team-id + :selected-files selected-files + :dragging? @dragging? + :limit limit}] + + :else + [:& empty-placeholder + {:dragging? @dragging? + :limit limit + :create-fn create-fn}])] + + ;; OLD + [:div.dashboard-grid {:on-drag-enter on-drag-enter + :on-drag-over on-drag-over + :on-drag-leave on-drag-leave + :on-drop on-drop} + (cond + (nil? files) + [:& loading-placeholder] + + (seq files) + [:& line-grid-row {:files files + :team-id team-id + :selected-files selected-files + :dragging? @dragging? + :limit limit}] + + :else + [:& empty-placeholder + {:dragging? @dragging? + :limit limit + :create-fn create-fn}])]))) - :else - [:& empty-placeholder - {:dragging? @dragging? - :limit limit - :create-fn create-fn}])])) diff --git a/frontend/src/app/main/ui/dashboard/grid.scss b/frontend/src/app/main/ui/dashboard/grid.scss new file mode 100644 index 0000000000..8446762ca6 --- /dev/null +++ b/frontend/src/app/main/ui/dashboard/grid.scss @@ -0,0 +1,517 @@ +@import "common/dependencies/colors"; + +$size-1: 0.25rem; +$size-2: 0.5rem; +$size-3: 0.75rem; +$size-4: 1rem; +$size-6: 2rem; +$fs12: 0.75rem; +$fs14: 0.875rem; +$fs18: 1.125rem; +$fw400: 400; +$fw500: 500; +$bp-max-1366: "(max-width: 1366px)"; +$br2: 2px; +$br3: 3px; +$br4: 4px; +$br5: 5px; +$lh-192: 1.92; + +.dashboard-grid { + font-size: $fs14; + height: 100%; + overflow: hidden; + overflow-y: auto; + margin-bottom: 0; + + .grid-row { + display: grid; + width: 99%; + margin-left: 13px; + } + + .grid-item { + align-items: center; + cursor: pointer; + display: flex; + flex-direction: column; + flex: 1 0 260px; + height: 230px; + margin: $size-3 $size-4 $size-4 $size-2; + position: relative; + text-align: center; + a, + button { + width: 100%; + font-weight: $fw400; + } + button { + background-color: transparent; + border: none; + } + @media #{$bp-max-1366} { + height: 200px; + flex: 1 0 230px; + } + + &:hover { + .grid-item-th { + border: 2px solid $color-primary; + } + } + + .grid-item-th { + border-radius: $br3; + border: 2px solid lighten($color-gray-20, 15%); + text-align: initial; + + img { + object-fit: contain; + } + } + + &.dragged { + border-radius: $br3; + border: 2px solid lighten($color-gray-20, 15%); + text-align: initial; + max-height: 160px; + } + + &.placeholder { + min-width: 115px; + max-width: 115px; + + display: flex; + flex-direction: column; + justify-content: center; + + .placeholder-icon { + svg { + transform: rotate(-90deg); + width: 20px; + height: 20px; + fill: $color-gray-30; + } + } + + .placeholder-label { + font-size: $fs14; + } + } + + &.overlay { + border-radius: $br4; + border: 2px solid $color-primary; + height: 100%; + opacity: 0; + pointer-events: none; + position: absolute; + width: 100%; + z-index: 1; + } + + &:hover .overlay { + display: block; + opacity: 1; + } + + &.small-item { + max-width: 12%; + min-width: 190px; + padding: $size-4; + justify-content: center; + } + + .grid-item-icon { + width: 90px; + height: 90px; + } + .info-wrapper { + display: grid; + grid-template-columns: 1fr auto; + } + + .item-info { + display: grid; + padding: $size-2; + text-align: left; + width: 100%; + font-size: $fs12; + + h3 { + border: 1px solid transparent; + color: $color-gray-60; + font-size: $fs14; + font-weight: $fw500; + overflow: hidden; + padding: 0; + height: 27px; + padding-right: $size-2; + text-overflow: ellipsis; + width: 100%; + white-space: nowrap; + line-height: $lh-192; // Original value was 27px; 27px/14px = 192.857142857% => $lh-192 (rounded) + max-width: 260px; + @media #{$bp-max-1366} { + max-width: 230px; + } + } + + span.date { + color: $color-gray-30; + overflow: hidden; + text-overflow: ellipsis; + width: 100%; + white-space: nowrap; + max-width: 260px; + &::first-letter { + text-transform: capitalize; + } + @media #{$bp-max-1366} { + max-width: 230px; + } + } + + .edit-wrapper { + .element-title { + padding: 0px; + height: 25px; + color: $color-gray-60; + font-size: $fs14; + font-weight: $fw400; + } + } + } + + .item-badge { + background-color: $color-white; + border: 1px solid $color-gray-20; + border-radius: $br2; + position: absolute; + top: $size-2; + right: $size-2; + height: 32px; + width: 32px; + display: flex; + align-items: center; + justify-content: center; + + svg { + fill: $color-gray-30; + height: 16px; + width: 16px; + } + } + + &.add-file { + border: 1px dashed $color-gray-20; + justify-content: center; + box-shadow: none; + + span { + color: $color-gray-60; + font-size: $fs14; + } + + &:hover { + background-color: $color-white; + border: 2px solid $color-primary; + } + } + + // PROJECTS, ELEMENTS & ICONS GRID + &.project-th { + background-color: $color-white; + + &:hover, + &:focus, + &:focus-within { + .project-th-actions { + opacity: 1; + } + a { + text-decoration: none; + } + } + + .selected { + .grid-item-th { + border: 2px solid $color-primary; + } + } + + .project-th-actions { + align-items: center; + opacity: 0; + display: flex; + right: 5px; + justify-content: center; + width: 30px; + height: 100%; + + span { + color: $color-black; + } + + .project-th-icon { + align-items: center; + display: flex; + margin-right: $size-2; + + &.menu { + margin-right: 0; + display: flex; + justify-content: center; + align-items: flex-end; + flex-direction: column; + width: 100%; + height: 30px; + margin-top: 20px; + + > svg { + fill: $color-gray-60; + margin-right: 0; + height: 18px; + width: 18px; + } + + &:hover, + &:focus { + > svg { + fill: $color-primary-dark; + } + } + } + } + } + + .project-th-actions.force-display { + opacity: 1; + } + } + + // IMAGES SECTION + &.images-th { + border: 1px dashed $color-gray-20; + border-bottom: 2px solid lighten($color-gray-20, 12%); + + &:hover { + border-color: $color-primary; + } + } + + .grid-item-image { + svg { + max-height: 100px; + max-width: 100px; + min-height: 40px; + min-width: 40px; + width: 8vw; + } + } + + .color-swatch { + border-top-left-radius: $br5; + border-top-right-radius: $br5; + height: 25%; + left: 0; + position: absolute; + top: 0; + width: 100%; + } + + .color-data { + color: $color-gray-30; + margin-top: 15px; + } + + .drag-counter { + position: absolute; + top: 5px; + left: 4px; + width: 32px; + height: 32px; + background-color: $color-primary; + border-radius: 50%; + color: $color-black; + font-size: $fs18; + display: flex; + justify-content: center; + align-items: center; + } + } + + .grid-item-th { + background-position: center; + background-size: auto 80%; + background-repeat: no-repeat; + border-top-left-radius: $br3; + border-top-right-radius: $br3; + height: 230px; + max-height: 160px; + overflow: hidden; + position: relative; + width: 100%; + + background-color: $color-canvas; + display: flex; + justify-content: center; + flex-direction: row; + + .img-th { + height: auto; + width: 100%; + } + + svg { + height: 100%; + width: 100%; + } + + svg#loader-pencil { + fill: $color-gray-20; + } + } + + // LIBRARY VIEW + .grid-item { + .library { + height: 580px; + } + + &.project-th.library { + height: 610px; + width: 300px; + } + + .grid-item-th.library { + background-color: $color-gray-50; + flex-direction: column; + height: 90%; + justify-content: flex-start; + max-height: 550px; + padding: $size-6; + + .asset-section { + font-size: $fs12; + color: $color-gray-20; + + &:not(:first-child) { + margin-top: $size-4; + } + } + + .asset-title { + display: flex; + font-size: $fs12; + text-transform: uppercase; + + & .num-assets { + color: $color-gray-30; + } + } + + .asset-list-item { + display: flex; + align-items: center; + border: 1px solid transparent; + border-radius: $br3; + margin-top: $size-1; + padding: 2px; + font-size: $fs12; + color: $color-white; + position: relative; + + & .name-block { + color: $color-gray-20; + width: calc(100% - 24px - #{$size-2}); + } + + & .item-name { + overflow: hidden; + text-overflow: ellipsis; + white-space: nowrap; + display: block; + } + + & svg { + background-color: $color-canvas; + border-radius: $br4; + border: 2px solid transparent; + height: 24px; + width: 24px; + margin-right: $size-2; + } + + & .color-name { + color: $color-white; + } + + & .color-value { + margin-left: $size-1; + color: $color-gray-30; + text-transform: uppercase; + } + + & .typography-sample { + height: 20px; + margin-right: $size-1; + width: 20px; + } + } + } + } +} + +.dashboard-grid { + .grid-item { + &.project-th { + background-color: transparent; + border-radius: 8px; + padding-top: 0.3rem; + .info-wrapper { + cursor: pointer; + .item-info { + h3 { + color: $df-primary; + font-size: 16px; + font-weight: 400; + } + } + .date { + color: $df-secondary; + } + .project-th-actions { + .project-th-icon { + margin-top: 0; + .icon-actions { + fill: $df-secondary; + } + } + } + } + + &:hover { + background-color: $db-tertiary; + .grid-item-th { + border: none; + } + } + } + + .grid-item-th { + border-radius: 4px; + border: none; + cursor: pointer; + } + + .item-badge { + background-color: $da-primary; + border: none; + border-radius: 4px; + svg { + fill: $db-secondary; + } + } + } +} diff --git a/frontend/src/app/main/ui/dashboard/inline_edition.cljs b/frontend/src/app/main/ui/dashboard/inline_edition.cljs index 13449aece4..3011ebdd5c 100644 --- a/frontend/src/app/main/ui/dashboard/inline_edition.cljs +++ b/frontend/src/app/main/ui/dashboard/inline_edition.cljs @@ -5,7 +5,9 @@ ;; Copyright (c) KALEIDOS INC (ns app.main.ui.dashboard.inline-edition + (:require-macros [app.main.style :as stl]) (:require + [app.main.ui.context :as ctx] [app.main.ui.icons :as i] [app.util.dom :as dom] [app.util.keyboard :as kbd] @@ -13,7 +15,8 @@ (mf/defc inline-edition [{:keys [content on-end] :as props}] - (let [name (mf/use-state content) + (let [new-css-system (mf/use-ctx ctx/new-css-system) + name (mf/use-state content) input-ref (mf/use-ref) on-input @@ -59,13 +62,26 @@ (dom/focus! node) (dom/select-text! node)))) - [:div.edit-wrapper - [:input.element-title {:value @name - :ref input-ref - :on-click on-click - :on-change on-input - :on-key-down on-keyup - :on-blur on-blur}] - [:span.close {:on-click on-cancel} i/close]])) + (if new-css-system + [:div {:class (stl/css :edit-wrapper)} + [:input {:class (stl/css :element-title) + :value @name + :ref input-ref + :on-click on-click + :on-change on-input + :on-key-down on-keyup + :on-blur on-blur}] + [:span {:class (stl/css :close) + :on-click on-cancel} i/close]] + + ;; OLD + [:div.edit-wrapper + [:input.element-title {:value @name + :ref input-ref + :on-click on-click + :on-change on-input + :on-key-down on-keyup + :on-blur on-blur}] + [:span.close {:on-click on-cancel} i/close]]))) diff --git a/frontend/src/app/main/ui/dashboard/inline_edition.scss b/frontend/src/app/main/ui/dashboard/inline_edition.scss new file mode 100644 index 0000000000..e69de29bb2 diff --git a/frontend/src/app/main/ui/dashboard/libraries.cljs b/frontend/src/app/main/ui/dashboard/libraries.cljs index fa14becee2..b065e19c5c 100644 --- a/frontend/src/app/main/ui/dashboard/libraries.cljs +++ b/frontend/src/app/main/ui/dashboard/libraries.cljs @@ -5,12 +5,14 @@ ;; Copyright (c) KALEIDOS INC (ns app.main.ui.dashboard.libraries + (:require-macros [app.main.style :as stl]) (:require [app.common.data :as d] [app.main.data.dashboard :as dd] [app.main.features :as features] [app.main.refs :as refs] [app.main.store :as st] + [app.main.ui.context :as ctx] [app.main.ui.dashboard.grid :refer [grid]] [app.main.ui.hooks :as hooks] [app.util.dom :as dom] @@ -19,7 +21,8 @@ (mf/defc libraries-page [{:keys [team] :as props}] - (let [files-map (mf/deref refs/dashboard-shared-files) + (let [new-css-system (mf/use-ctx ctx/new-css-system) + files-map (mf/deref refs/dashboard-shared-files) projects (mf/deref refs/dashboard-projects) default-project (->> projects vals (d/seek :is-default)) @@ -46,14 +49,27 @@ (st/emit! (dd/fetch-shared-files) (dd/clear-selected-files))) - [:* - [:header.dashboard-header {:ref rowref} - [:div.dashboard-title#dashboard-libraries-title - [:h1 (tr "dashboard.libraries-title")]]] - [:section.dashboard-container.no-bg.dashboard-shared - [:& grid {:files files - :project default-project - :origin :libraries - :limit limit - :library-view? components-v2}]]])) + (if new-css-system + [:* + [:header {:class (stl/css :dashboard-header) :ref rowref} + [:div#dashboard-libraries-title {:class (stl/css :dashboard-title)} + [:h1 (tr "dashboard.libraries-title")]]] + [:section {:class (stl/css :dashboard-container :no-bg :dashboard-shared)} + [:& grid {:files files + :project default-project + :origin :libraries + :limit limit + :library-view? components-v2}]]] + + ;; OLD + [:* + [:header.dashboard-header {:ref rowref} + [:div.dashboard-title#dashboard-libraries-title + [:h1 (tr "dashboard.libraries-title")]]] + [:section.dashboard-container.no-bg.dashboard-shared + [:& grid {:files files + :project default-project + :origin :libraries + :limit limit + :library-view? components-v2}]]]))) diff --git a/frontend/src/app/main/ui/dashboard/libraries.scss b/frontend/src/app/main/ui/dashboard/libraries.scss new file mode 100644 index 0000000000..443f1b6364 --- /dev/null +++ b/frontend/src/app/main/ui/dashboard/libraries.scss @@ -0,0 +1,752 @@ +@import "common/dependencies/colors"; + +// FIXME: Mostly duplcated from projects.css + +$br3: 3px; +$fs14: 0.875rem; +$fs18: 1.125rem; +$fs22: 1.375rem; +$fw400: 400; +$fw600: 600; +$lh-088: 0.88; +$lh-115: 1.15; // original $title-lh-sm +$size-1: 0.25rem; +$size-2: 0.5rem; +$size-4: 1rem; +$size-5: 1.5rem; +$size-6: 2rem; + +.dashboard-header { + display: flex; + align-items: center; + justify-content: space-between; + background-color: $color-white; + height: 63px; + padding: $size-1 $size-4 $size-1 $size-2; + position: relative; + z-index: 10; + user-select: none; + &.team { + display: grid; + grid-template-columns: 20% 1fr 20%; + } + + .element-name { + margin-right: $size-2; + } + + .btn-secondary { + flex-shrink: 0; + z-index: 10; + height: 32px; + svg { + height: 16px; + width: 16px; + } + } + + svg { + fill: $color-black; + height: 14px; + margin-right: $size-1; + width: 14px; + } + + nav { + display: flex; + align-items: flex-end; + justify-content: center; + z-index: 1; + + ul { + display: flex; + font-size: $fs14; + justify-content: center; + margin: 0; + } + + li { + a { + display: flex; + align-items: center; + flex-basis: 140px; + border-bottom: 3px solid transparent; + color: $color-gray-30; + height: 40px; + padding: $size-1 $size-5; + font-weight: $fw400; + &:hover { + color: $color-black; + text-decoration: none; + } + } + + &.active { + a { + color: $color-black; + border-color: $color-primary; + } + } + } + } + + .dashboard-title { + display: flex; + align-items: center; + margin-left: 13px; + + h1 { + color: $color-black; + display: flex; + flex-shrink: 0; + font-size: $fs22; + font-weight: $fw600; + z-index: 10; + user-select: all; + } + + .context-menu.is-open { + margin-top: 10px; + } + } + + .icon { + display: flex; + align-items: center; + cursor: pointer; + margin-left: $size-2; + z-index: 10; + + svg { + fill: $color-gray-40; + width: 15px; + height: 15px; + + &:hover { + fill: $color-primary-dark; + } + } + } + + .dashboard-buttons { + display: flex; + justify-content: flex-end; + align-items: center; + } + + .dashboard-header-actions { + display: flex; + } + + .pin-icon { + margin: 0 $size-2 0 $size-5; + background-color: transparent; + border: none; + svg { + fill: $color-gray-20; + } + + &.active { + svg { + fill: $color-gray-50; + } + } + } +} + +.dashboard-header { + background-color: transparent; + .dashboard-title { + h1 { + color: $df-primary; + font-size: 24px; + font-weight: 400; + width: 100%; + text-overflow: ellipsis; + overflow: hidden; + white-space: nowrap; + display: block; + max-width: 700px; + } + } + .icon { + svg { + fill: $df-secondary; + } + } + + // Settings sub-menu + .dashboard-header-options { + li { + a { + font-size: 16px; + color: $df-secondary; + border-color: transparent; + &:hover { + color: $df-primary; + } + } + &.active { + a { + color: $df-primary; + } + } + } + } +} + +.dashboard-container { + background-color: $color-dashboard; + flex: 1 0 0; + margin-right: $size-4; + overflow-y: auto; + width: 100%; + &.dashboard-projects { + user-select: none; + } + &.no-bg { + background-color: transparent; + } + &.dashboard-shared { + width: calc(100vw - 320px); + margin-right: 50px; + } + + &.search { + margin-top: 10px; + } +} + +.dashboard-container { + background-color: transparent; + border-top: 1px solid $db-cuaternary; + + .dashboard-settings { + a { + color: $df-secondary; + } + .form-container { + width: 800px; + margin: 80px auto auto 120px; + form { + width: 468px; + .fields-row { + .custom-input, + .custom-select { + flex-direction: column-reverse; + label { + position: relative; + text-transform: uppercase; + color: $df-primary; + font-size: 11px; + margin-bottom: 12px; + margin-left: -4px; + } + input, + select { + background-color: $db-tertiary; + border-radius: 8px; + border-color: transparent; + color: $df-primary; + padding: 0 15px; + &:focus { + outline: 1px solid $da-primary; + } + ::placeholder { + color: $df-secondary; + } + } + .help-icon { + bottom: 12px; + top: auto; + svg { + fill: $df-secondary; + } + } + &.disabled { + input { + background-color: $db-primary; + border-color: $db-cuaternary; + color: $df-secondary; + } + } + .input-container { + background-color: $db-tertiary; + border-radius: 8px; + border-color: transparent; + margin-top: 22px; + .main-content { + label { + position: absolute; + top: -24px; + } + span { + color: $df-primary; + } + } + &:focus { + border: 1px solid $da-primary; + } + } + textarea { + border-radius: 8px; + padding: 12px 14px; + background-color: $db-tertiary; + color: $df-primary; + border: none; + &:focus { + outline: 1px solid $da-primary; + } + } + } + } + .field-title { + color: $df-primary; + } + .field-title:not(:first-child) { + margin-top: 64px; + } + + .field-text { + color: $df-secondary; + } + button, + .btn-secondary { + width: 100%; + font-size: 11px; + text-transform: uppercase; + background-color: $db-tertiary; + color: $df-primary; + &:hover { + color: $da-primary; + background-color: $db-cuaternary; + } + } + hr { + display: none; + } + } + .links { + margin-top: 12px; + } + } + } + + //Access tokens + .dashboard-access-tokens { + width: 800px; + margin-left: 120px; + margin-top: 80px; + .access-tokens-hero-container { + background-color: transparent; + .access-tokens-hero { + width: 468px; + flex-direction: column; + gap: 32px; + background-color: transparent; + margin: 0; + padding: 0; + .desc { + background-color: transparent; + width: 100%; + h2 { + color: $df-primary; + font-size: 24px; + font-weight: regular; + margin-bottom: 32px; + } + p { + color: $df-secondary; + margin-bottom: 0; + font-size: 14px; + } + } + button { + width: 100%; + font-size: 11px; + text-transform: uppercase; + background-color: $db-tertiary; + color: $df-primary; + &:hover { + color: $da-primary; + background-color: $db-cuaternary; + } + } + } + } + .dashboard-table { + width: 800px; + .table-rows { + padding-top: 0; + .table-row { + font-size: 14px; + min-height: 40px; + height: fit-content; + .name { + color: $df-primary; + max-width: 480px; + overflow: hidden; + text-overflow: ellipsis; + display: -webkit-box; + -webkit-line-clamp: 2; + -webkit-box-orient: vertical; + } + .expiration-date { + color: $df-secondary; + } + } + } + } + .access-tokens-empty { + width: 468px; + border: 1px solid $db-cuaternary; + border-radius: 8px; + margin-top: 32px; + font-size: 14px; + background-color: transparent; + color: $df-secondary; + } + } + + // Team webhooks + &.dashboard-team-webhooks { + width: 800px; + margin-left: 120px; + margin-top: 80px; + border: none; + align-items: flex-start; + .webhooks-hero-container { + width: 468px; + background-color: transparent; + .webhooks-hero { + width: 468px; + flex-direction: column; + gap: 32px; + background-color: transparent; + margin: 0; + padding: 0; + .desc { + background-color: transparent; + width: 100%; + h2 { + color: $df-primary; + font-size: 24px; + font-weight: regular; + margin-bottom: 32px; + } + p { + color: $df-secondary; + margin-bottom: 0; + font-size: 14px; + } + } + .btn-primary { + width: 100%; + font-size: 11px; + text-transform: uppercase; + background-color: $db-tertiary; + color: $df-primary; + &:hover { + color: $da-primary; + background-color: $db-cuaternary; + } + } + } + } + .dashboard-table { + width: 800px; + .table-rows { + padding-top: 0; + .table-row { + font-size: 14px; + min-height: 40px; + height: fit-content; + .name { + color: $df-primary; + max-width: 480px; + } + .expiration-date { + color: $df-secondary; + } + } + } + } + .webhooks-empty { + width: 468px; + border: 1px solid $db-cuaternary; + border-radius: 8px; + margin-top: 32px; + font-size: 14px; + background-color: transparent; + color: $df-secondary; + } + } + + // Members section + .dashboard-table { + .table-header { + background-color: transparent; + color: $df-secondary; + font-size: 12px; + text-transform: uppercase; + } + .table-rows { + .table-row { + background-color: $db-tertiary; + border-radius: 8px; + color: $df-primary; + .rol-selector { + background-color: $db-cuaternary; + border-color: transparent; + border-radius: 8px; + } + } + } + .member-info { + .member-name .you, + .member-email { + color: $df-secondary; + } + } + .status-badge { + border-radius: 8px; + color: $db-primary; + text-transform: uppercase; + } + .empty-invitations { + border: 1px solid $db-cuaternary; + border-radius: 8px; + color: $df-secondary; + } + } + .actions-dropdown, + .options-dropdown { + background-color: $db-tertiary; + border: 1px solid $db-cuaternary; + border-radius: 8px; + min-width: 252px; + + .separator { + border-color: transparent; + margin-top: 10px; + } + + li { + border-radius: 8px; + height: 40px; + margin: 5px; + color: $df-primary; + + &:hover { + background-color: $db-cuaternary; + } + } + + &.options-dropdown { + li { + color: $df-primary; + &.warning { + color: $color-danger; + } + } + } + } +} + +.dashboard-project-row { + margin-bottom: $size-5; + position: relative; + + .project { + align-items: center; + background: $color-white; + border-radius: $br3; + display: flex; + flex-direction: row; + justify-content: space-between; + align-items: center; + margin-top: $size-4; + padding: $size-2 $size-2 $size-2 $size-4; + width: 99%; + max-height: 40px; + gap: $size-2; + .project-name-wrapper { + display: flex; + align-items: center; + justify-content: flex-start; + min-height: 32px; + margin-left: $size-2; + } + .show-more { + align-items: center; + color: $color-gray-30; + display: flex; + font-size: $fs14; + justify-content: space-between; + cursor: pointer; + background-color: transparent; + border: none; + .placeholder-icon { + transform: rotate(-90deg); + margin-left: 10px; + svg { + height: 14px; + width: 14px; + fill: $color-gray-30; + } + } + &:hover { + color: $color-primary-dark; + svg { + fill: $color-primary-dark; + } + } + } + + .btn-secondary { + border: none; + padding: $size-2; + } + + h2 { + cursor: pointer; + font-size: $fs18; + line-height: $lh-088; // Original value was 1rem = 16px; 16px/18px = 88.88888% => $lh-088 + font-weight: $fw600; + color: $color-black; + margin-right: $size-1; + } + + .edit-wrapper { + margin-right: $size-4; + } + + .info { + font-size: $fs14; + line-height: $lh-115; // Original value was 1rem = 16px; 16px/14px = 114.285714286% => $lh-115 (rounded) + font-weight: $fw400; + color: $color-gray-60; + margin-left: 0.75rem; + @media (max-width: 760px) { + display: none; + } + } + + .project-actions { + display: flex; + opacity: 1; + margin-left: $size-6; + + .btn-small { + height: 32px; + margin: 0 $size-2; + width: 32px; + svg { + height: 16px; + width: 16px; + } + } + } + + .pin-icon { + cursor: pointer; + display: flex; + align-items: center; + margin-right: 14px; + background-color: transparent; + border: none; + svg { + width: 15px; + height: 15px; + fill: $color-gray-20; + } + + &.active { + svg { + fill: $color-gray-50; + } + } + } + } + + &:hover, + &:focus, + &:focus-within { + .project-actions { + opacity: 1; + } + } + + .show-more { + align-items: center; + color: $color-gray-30; + display: flex; + font-size: $fs14; + justify-content: space-between; + cursor: pointer; + background-color: transparent; + border: none; + position: absolute; + top: 9px; + right: 53px; + .placeholder-icon { + transform: rotate(-90deg); + margin-left: 10px; + svg { + height: 14px; + width: 14px; + fill: $color-gray-30; + } + } + &:hover { + color: $color-primary-dark; + svg { + fill: $color-primary-dark; + } + } + } +} + +.dashboard-project-row .project { + background-color: transparent; + + h2 { + color: $df-primary; + font-weight: 400; + } + span, + .info { + color: $df-secondary; + } + .project-actions { + svg { + fill: $df-primary; + } + .pin-icon svg { + fill: $df-secondary; + } + } +} + +.btn-secondary { + background-color: $db-tertiary; + text-transform: uppercase; + border: none; + color: $df-primary; + border-radius: 8px; + + font-size: 0.75rem; + padding: 0 1rem; + cursor: pointer; + display: flex; + justify-content: center; + align-items: center; + + &:hover { + background-color: $db-cuaternary; + color: $da-primary; + svg { + fill: $da-primary; + } + } +} diff --git a/frontend/src/app/main/ui/dashboard/placeholder.cljs b/frontend/src/app/main/ui/dashboard/placeholder.cljs index 9b22d63303..4d4e5e25fb 100644 --- a/frontend/src/app/main/ui/dashboard/placeholder.cljs +++ b/frontend/src/app/main/ui/dashboard/placeholder.cljs @@ -5,37 +5,68 @@ ;; Copyright (c) KALEIDOS INC (ns app.main.ui.dashboard.placeholder + (:require-macros [app.main.style :as stl]) (:require + [app.main.ui.context :as ctx] [app.main.ui.icons :as i] [app.util.i18n :as i18n :refer [tr]] [rumext.v2 :as mf])) (mf/defc empty-placeholder [{:keys [dragging? limit origin create-fn] :as props}] - (let [on-click + (let [new-css-system (mf/use-ctx ctx/new-css-system) + on-click (mf/use-fn (mf/deps create-fn) (fn [_] (create-fn "dashboard:empty-folder-placeholder")))] - (cond - (true? dragging?) - [:ul.grid-row.no-wrap - {:style {:grid-template-columns (str "repeat(" limit ", 1fr)")}} - [:li.grid-item]] + (if new-css-system + (cond + (true? dragging?) + [:ul + {:class (stl/css :grid-row :no-wrap) + :style {:grid-template-columns (str "repeat(" limit ", 1fr)")}} + [:li {:class (stl/css :grid-item)}]] - (= :libraries origin) - [:div.grid-empty-placeholder.libs {:data-test "empty-placeholder"} - [:div.text - [:& i18n/tr-html {:label "dashboard.empty-placeholder-drafts"}]]] + (= :libraries origin) + [:div {:class (stl/css :grid-empty-placeholder :libs) + :data-test "empty-placeholder"} + [:div {:class (stl/css :text)} + [:& i18n/tr-html {:label "dashboard.empty-placeholder-drafts"}]]] - :else - [:div.grid-empty-placeholder - {:style {:grid-template-columns (str "repeat(" limit ", 1fr)")}} - [:button.create-new {:on-click on-click} (tr "dashboard.new-file")]]))) + :else + [:div + {:class (stl/css :grid-empty-placeholder) + :style {:grid-template-columns (str "repeat(" limit ", 1fr)")}} + [:button {:class (stl/css :create-new) + :on-click on-click} (tr "dashboard.new-file")]]) + + ;; OLD + (cond + (true? dragging?) + [:ul.grid-row.no-wrap + {:style {:grid-template-columns (str "repeat(" limit ", 1fr)")}} + [:li.grid-item]] + + (= :libraries origin) + [:div.grid-empty-placeholder.libs {:data-test "empty-placeholder"} + [:div.text + [:& i18n/tr-html {:label "dashboard.empty-placeholder-drafts"}]]] + + :else + [:div.grid-empty-placeholder + {:style {:grid-template-columns (str "repeat(" limit ", 1fr)")}} + [:button.create-new {:on-click on-click} (tr "dashboard.new-file")]])))) (mf/defc loading-placeholder [] - [:div.grid-empty-placeholder.loader - [:div.icon i/loader] - [:div.text (tr "dashboard.loading-files")]]) + (let [new-css-system (mf/use-ctx ctx/new-css-system)] + (if new-css-system + [:div {:class (stl/css :grid-empty-placeholder :loader)} + [:div {:class (stl/css :icon)} i/loader] + [:div {:class (stl/css :text)} (tr "dashboard.loading-files")]] + + [:div.grid-empty-placeholder.loader + [:div.icon i/loader] + [:div.text (tr "dashboard.loading-files")]]))) diff --git a/frontend/src/app/main/ui/dashboard/placeholder.scss b/frontend/src/app/main/ui/dashboard/placeholder.scss new file mode 100644 index 0000000000..220f2152a0 --- /dev/null +++ b/frontend/src/app/main/ui/dashboard/placeholder.scss @@ -0,0 +1,112 @@ +@import "common/dependencies/colors"; + +$br0: 0; +$br3: 3px; +$br12: 12px; +$fs16: 1rem; + +.grid-empty-placeholder { + border-radius: $br12; + display: grid; + background-color: rgba(227, 227, 227, 0.3); + padding: 13px; + margin-right: 13px; + height: 230px; + &.loader { + justify-items: center; + } + .icon { + display: flex; + align-items: center; + justify-content: center; + } + &.libs { + background-image: url(/images/ph-left.svg), url(/images/ph-right.svg); + background-position: + 15% bottom, + 85% top; + background-repeat: no-repeat; + align-items: center; + border: 1px dashed #b1b2b5; + border-radius: $br3; + display: flex; + flex-direction: column; + height: 200px; + margin: 1rem; + padding: 3rem; + justify-content: center; + .text { + p { + max-width: 360px; + text-align: center; + font-size: $fs16; + } + } + } + .create-new { + background-color: white; + border: 2px solid $color-gray-10; + border-radius: $br3; + color: $color-black; + cursor: pointer; + height: 158px; + font-family: "worksans", sans-serif; + margin: 0.5rem; + &:hover { + border: 2px solid $color-primary; + } + } + + &.search { + align-items: center; + display: flex; + justify-content: center; + flex-direction: column; + height: 200px; + background: $color-white; + border: 1px dashed #e3e3e3; + border-radius: $br0; + } + + svg { + width: 36px; + height: 36px; + fill: $color-gray-20; + } + + .text { + margin-top: 10px; + color: $color-gray-30; + font-size: $fs16; + } +} + +.grid-empty-placeholder { + background-color: transparent; + + .create-new { + background-color: $db-tertiary; + border-radius: 8px; + border: none; + color: $df-primary; + text-transform: uppercase; + + &:hover { + background-color: $db-cuaternary; + color: $da-primary; + } + } + + &.search { + border: 1px solid $db-cuaternary; + border-radius: 8px; + .text { + color: $df-primary; + } + .icon { + svg { + fill: $df-secondary; + } + } + } +} diff --git a/frontend/src/app/main/ui/dashboard/projects.cljs b/frontend/src/app/main/ui/dashboard/projects.cljs index 0455c4aaf4..d97dc9a16b 100644 --- a/frontend/src/app/main/ui/dashboard/projects.cljs +++ b/frontend/src/app/main/ui/dashboard/projects.cljs @@ -5,6 +5,7 @@ ;; Copyright (c) KALEIDOS INC (ns app.main.ui.dashboard.projects + (:require-macros [app.main.style :as stl]) (:require [app.common.data :as d] [app.common.geom.point :as gpt] @@ -16,6 +17,7 @@ [app.main.data.users :as du] [app.main.refs :as refs] [app.main.store :as st] + [app.main.ui.context :as ctx] [app.main.ui.dashboard.grid :refer [line-grid]] [app.main.ui.dashboard.inline-edition :refer [inline-edition]] [app.main.ui.dashboard.project-menu :refer [project-menu]] @@ -34,19 +36,32 @@ (mf/defc header {::mf/wrap [mf/memo]} [] - (let [on-click (mf/use-fn #(st/emit! (dd/create-project)))] - [:header.dashboard-header - [:div.dashboard-title#dashboard-projects-title - [:h1 (tr "dashboard.projects-title")]] - [:button.btn-secondary.btn-small - {:on-click on-click - :data-test "new-project-button"} - (tr "dashboard.new-project")]])) + (let [new-css-system (mf/use-ctx ctx/new-css-system) + on-click (mf/use-fn #(st/emit! (dd/create-project)))] + (if new-css-system + [:header {:class (stl/css :dashboard-header)} + [:div#dashboard-projects-title {:class (stl/css :dashboard-title)} + [:h1 (tr "dashboard.projects-title")]] + [:button + {:class (stl/css :btn-secondary :btn-small) + :on-click on-click + :data-test "new-project-button"} + (tr "dashboard.new-project")]] + + ;; OLD + [:header.dashboard-header + [:div.dashboard-title#dashboard-projects-title + [:h1 (tr "dashboard.projects-title")]] + [:button.btn-secondary.btn-small + {:on-click on-click + :data-test "new-project-button"} + (tr "dashboard.new-project")]]))) (mf/defc team-hero {::mf/wrap [mf/memo]} [{:keys [team close-fn] :as props}] - (let [on-nav-members-click (mf/use-fn #(st/emit! (dd/go-to-team-members))) + (let [new-css-system (mf/use-ctx ctx/new-css-system) + on-nav-members-click (mf/use-fn #(st/emit! (dd/go-to-team-members))) on-invite-click (mf/use-fn @@ -62,28 +77,49 @@ (dom/prevent-default event) (close-fn)))] - [:div.team-hero - [:img {:src "images/deco-team-banner.png" :border "0" - :role "presentation"}] - [:div.text - [:div.title (tr "dasboard.team-hero.title")] - [:div.info - [:span (tr "dasboard.team-hero.text")] - [:a {:on-click on-nav-members-click} (tr "dasboard.team-hero.management")]]] - [:button.btn-primary.invite - {:on-click on-invite-click} - (tr "onboarding.choice.team-up.invite-members")] - [:button.close - {:on-click on-close-click - :aria-label (tr "labels.close")} - [:span i/close]]])) + (if new-css-system + [:div {:class (stl/css :team-hero)} + [:img {:src "images/deco-team-banner.png" :border "0" + :role "presentation"}] + [:div {:class (stl/css :text)} + [:div {:class (stl/css :title)} (tr "dasboard.team-hero.title")] + [:div {:class (stl/css :info)} + [:span (tr "dasboard.team-hero.text")] + [:a {:on-click on-nav-members-click} (tr "dasboard.team-hero.management")]]] + [:button + {:class (stl/css :btn-primary :invite) + :on-click on-invite-click} + (tr "onboarding.choice.team-up.invite-members")] + [:button + {:class (stl/css :close) + :on-click on-close-click + :aria-label (tr "labels.close")} + [:span i/close]]] + + ;; OLD + [:div.team-hero + [:img {:src "images/deco-team-banner.png" :border "0" + :role "presentation"}] + [:div.text + [:div.title (tr "dasboard.team-hero.title")] + [:div.info + [:span (tr "dasboard.team-hero.text")] + [:a {:on-click on-nav-members-click} (tr "dasboard.team-hero.management")]]] + [:button.btn-primary.invite + {:on-click on-invite-click} + (tr "onboarding.choice.team-up.invite-members")] + [:button.close + {:on-click on-close-click + :aria-label (tr "labels.close")} + [:span i/close]]]))) (def builtin-templates (l/derived :builtin-templates st/state)) (mf/defc tutorial-project [{:keys [close-tutorial default-project-id] :as props}] - (let [state (mf/use-state {:status :waiting + (let [new-css-system (mf/use-ctx ctx/new-css-system) + state (mf/use-state {:status :waiting :file nil}) templates (mf/deref builtin-templates) @@ -113,48 +149,88 @@ (swap! state #(assoc % :status :importing)) (st/emit! (with-meta (dd/clone-template (with-meta params mdata)) {::ev/origin "get-started-hero-block"})))))] - [:article.tutorial - [:div.thumbnail] - [:div.text - [:h2.title (tr "dasboard.tutorial-hero.title")] - [:p.info (tr "dasboard.tutorial-hero.info")] - [:button.btn-primary.action {:on-click download-tutorial} - (case (:status @state) - :waiting (tr "dasboard.tutorial-hero.start") - :importing [:span.loader i/loader-pencil] - :success "")]] + (if new-css-system + [:article {:class (stl/css :tutorial)} + [:div {:class (stl/css :thumbnail)}] + [:div {:class (stl/css :text)} + [:h2 {:class (stl/css :title)} (tr "dasboard.tutorial-hero.title")] + [:p {:clas (stl/css :info)} (tr "dasboard.tutorial-hero.info")] + [:button {:class (stl/css :btn-primary :action) + :on-click download-tutorial} + (case (:status @state) + :waiting (tr "dasboard.tutorial-hero.start") + :importing [:span.loader i/loader-pencil] + :success "")]] - [:button.close - {:on-click close-tutorial - :aria-label (tr "labels.close")} - [:span.icon i/close]]])) + [:button + {:class (stl/css :close) + :on-click close-tutorial + :aria-label (tr "labels.close")} + [:span {:class (stl/css :icon)} i/close]]] + + ;; OLD + [:article.tutorial + [:div.thumbnail] + [:div.text + [:h2.title (tr "dasboard.tutorial-hero.title")] + [:p.info (tr "dasboard.tutorial-hero.info")] + [:button.btn-primary.action {:on-click download-tutorial} + (case (:status @state) + :waiting (tr "dasboard.tutorial-hero.start") + :importing [:span.loader i/loader-pencil] + :success "")]] + + [:button.close + {:on-click close-tutorial + :aria-label (tr "labels.close")} + [:span.icon i/close]]]))) (mf/defc interface-walkthrough {::mf/wrap [mf/memo]} [{:keys [close-walkthrough] :as props}] - (let [handle-walkthrough-link + (let [new-css-system (mf/use-ctx ctx/new-css-system) + handle-walkthrough-link (fn [] (st/emit! (ptk/event ::ev/event {::ev/name "show-walkthrough" ::ev/origin "get-started-hero-block" :section "dashboard"})))] - [:article.walkthrough - [:div.thumbnail] - [:div.text - [:h2.title (tr "dasboard.walkthrough-hero.title")] - [:p.info (tr "dasboard.walkthrough-hero.info")] - [:a.btn-primary.action - {:href " https://design.penpot.app/walkthrough" - :target "_blank" - :on-click handle-walkthrough-link} - (tr "dasboard.walkthrough-hero.start")]] - [:button.close - {:on-click close-walkthrough - :aria-label (tr "labels.close")} - [:span.icon i/close]]])) + (if new-css-system + [:article {:class (stl/css :walkthrough)} + [:div {:class (stl/css :thumbnail)}] + [:div {:class (stl/css :text)} + [:h2 {:class (stl/css :title)} (tr "dasboard.walkthrough-hero.title")] + [:p {:class (stl/css :info)} (tr "dasboard.walkthrough-hero.info")] + [:a {:class (stl/css :btn-primary :action) + :href " https://design.penpot.app/walkthrough" + :target "_blank" + :on-click handle-walkthrough-link} + (tr "dasboard.walkthrough-hero.start")]] + [:button + {:class (stl/css :close) + :on-click close-walkthrough + :aria-label (tr "labels.close")} + [:span {:class (stl/css :icon)} i/close]]] + + ;; OLD + [:article.walkthrough + [:div.thumbnail] + [:div.text + [:h2.title (tr "dasboard.walkthrough-hero.title")] + [:p.info (tr "dasboard.walkthrough-hero.info")] + [:a.btn-primary.action + {:href " https://design.penpot.app/walkthrough" + :target "_blank" + :on-click handle-walkthrough-link} + (tr "dasboard.walkthrough-hero.start")]] + [:button.close + {:on-click close-walkthrough + :aria-label (tr "labels.close")} + [:span.icon i/close]]]))) (mf/defc project-item [{:keys [project first? team files] :as props}] - (let [locale (mf/deref i18n/locale) + (let [new-css-system (mf/use-ctx ctx/new-css-system) + locale (mf/deref i18n/locale) file-count (or (:count project) 0) project-id (:id project) team-id (:id team) @@ -247,84 +323,172 @@ (dd/fetch-projects (:id team)) (dd/clear-selected-files))))] - [:article.dashboard-project-row - {:class (when first? "first")} - [:header.project {:ref rowref} - [:div.project-name-wrapper - (if (:edition? @local) - [:& inline-edition {:content (:name project) - :on-end on-edit}] - [:h2 {:on-click on-nav - :on-context-menu on-menu-click} - (if (:is-default project) - (tr "labels.drafts") - (:name project))]) + (if new-css-system + [:article {:class (stl/css-case :dashboard-project-row true :first first?)} + [:header {:class (stl/css :project) :ref rowref} + [:div {:class (stl/css :project-name-wrapper)} + (if (:edition? @local) + [:& inline-edition {:content (:name project) + :on-end on-edit}] + [:h2 {:on-click on-nav + :on-context-menu on-menu-click} + (if (:is-default project) + (tr "labels.drafts") + (:name project))]) - [:& project-menu + [:& project-menu + {:project project + :show? (:menu-open @local) + :left (+ 24 (:x (:menu-pos @local))) + :top (:y (:menu-pos @local)) + :on-edit on-edit-open + :on-menu-close on-menu-close + :on-import on-import}] + + [:span {:class (stl/css :info)} (str (tr "labels.num-of-files" (i18n/c file-count)))] + + (let [time (-> (:modified-at project) + (dt/timeago {:locale locale}))] + [:span {:class (stl/css :recent-files-row-title-info)} (str ", " time)]) + + [:div {:class (stl/css :project-actions)} + (when-not (:is-default project) + [:button + {:class (stl/css-case :pin-icon true + :tooltip true + :tooltip-bottom true + :active (:is-pinned project)) + :on-click toggle-pin + :alt (tr "dashboard.pin-unpin") + :aria-label (tr "dashboard.pin-unpin") + :tab-index "0"} + (if (:is-pinned project) + i/pin-fill + i/pin)]) + + [:button + {:class (stl/css :btn-secondary :btn-small :tooltip :tooltip-bottom) + :on-click on-create-click + :alt (tr "dashboard.new-file") + :aria-label (tr "dashboard.new-file") + :data-test "project-new-file" + :tab-index "0" + :on-key-down (fn [event] + (when (kbd/enter? event) + (on-create-click event)))} + i/close] + + [:button + {:class (stl/css :btn-secondary :btn-small :tooltip :tooltip-bottom) + :on-click on-menu-click + :alt (tr "dashboard.options") + :aria-label (tr "dashboard.options") + :data-test "project-options" + :tab-index "0" + :on-key-down (fn [event] + (when (kbd/enter? event) + (dom/stop-propagation event) + (on-menu-click event)))} + i/actions]]]] + + [:& line-grid {:project project - :show? (:menu-open @local) - :left (+ 24 (:x (:menu-pos @local))) - :top (:y (:menu-pos @local)) - :on-edit on-edit-open - :on-menu-close on-menu-close - :on-import on-import}] + :team team + :files files + :create-fn create-file + :limit limit}] - [:span.info (str (tr "labels.num-of-files" (i18n/c file-count)))] - (let [time (-> (:modified-at project) - (dt/timeago {:locale locale}))] - [:span.recent-files-row-title-info (str ", " time)]) - [:div.project-actions - (when-not (:is-default project) - [:button.pin-icon.tooltip.tooltip-bottom - {:class (when (:is-pinned project) "active") - :on-click toggle-pin - :alt (tr "dashboard.pin-unpin") - :aria-label (tr "dashboard.pin-unpin") - :tab-index "0"} - (if (:is-pinned project) - i/pin-fill - i/pin)]) + (when (and (> limit 0) + (> file-count limit)) + [:button + {:class (stl/css :show-more) + :on-click on-nav + :tab-index "0" + :on-key-down (fn [event] + (when (kbd/enter? event) + (on-nav)))} + [:div {:class (stl/css :placeholder-label)} (tr "dashboard.show-all-files")] + [:div {:class (stl/css :placeholder-icon)} i/arrow-down]])] - [:button.btn-secondary.btn-small.tooltip.tooltip-bottom - {:on-click on-create-click - :alt (tr "dashboard.new-file") - :aria-label (tr "dashboard.new-file") - :data-test "project-new-file" - :tab-index "0" - :on-key-down (fn [event] - (when (kbd/enter? event) - (on-create-click event)))} - i/close] + ;; OLD + [:article.dashboard-project-row + {:class (when first? "first")} + [:header.project {:ref rowref} + [:div.project-name-wrapper + (if (:edition? @local) + [:& inline-edition {:content (:name project) + :on-end on-edit}] + [:h2 {:on-click on-nav + :on-context-menu on-menu-click} + (if (:is-default project) + (tr "labels.drafts") + (:name project))]) - [:button.btn-secondary.btn-small.tooltip.tooltip-bottom - {:on-click on-menu-click - :alt (tr "dashboard.options") - :aria-label (tr "dashboard.options") - :data-test "project-options" - :tab-index "0" - :on-key-down (fn [event] - (when (kbd/enter? event) - (dom/stop-propagation event) - (on-menu-click event)))} - i/actions]]]] + [:& project-menu + {:project project + :show? (:menu-open @local) + :left (+ 24 (:x (:menu-pos @local))) + :top (:y (:menu-pos @local)) + :on-edit on-edit-open + :on-menu-close on-menu-close + :on-import on-import}] - [:& line-grid - {:project project - :team team - :files files - :create-fn create-file - :limit limit}] + [:span.info (str (tr "labels.num-of-files" (i18n/c file-count)))] + (let [time (-> (:modified-at project) + (dt/timeago {:locale locale}))] + [:span.recent-files-row-title-info (str ", " time)]) + [:div.project-actions + (when-not (:is-default project) + [:button.pin-icon.tooltip.tooltip-bottom + {:class (when (:is-pinned project) "active") + :on-click toggle-pin + :alt (tr "dashboard.pin-unpin") + :aria-label (tr "dashboard.pin-unpin") + :tab-index "0"} + (if (:is-pinned project) + i/pin-fill + i/pin)]) - (when (and (> limit 0) - (> file-count limit)) - [:button.show-more {:on-click on-nav - :tab-index "0" - :on-key-down (fn [event] - (when (kbd/enter? event) - (on-nav)))} - [:div.placeholder-label - (tr "dashboard.show-all-files")] - [:div.placeholder-icon i/arrow-down]])])) + [:button.btn-secondary.btn-small.tooltip.tooltip-bottom + {:on-click on-create-click + :alt (tr "dashboard.new-file") + :aria-label (tr "dashboard.new-file") + :data-test "project-new-file" + :tab-index "0" + :on-key-down (fn [event] + (when (kbd/enter? event) + (on-create-click event)))} + i/close] + + [:button.btn-secondary.btn-small.tooltip.tooltip-bottom + {:on-click on-menu-click + :alt (tr "dashboard.options") + :aria-label (tr "dashboard.options") + :data-test "project-options" + :tab-index "0" + :on-key-down (fn [event] + (when (kbd/enter? event) + (dom/stop-propagation event) + (on-menu-click event)))} + i/actions]]]] + + [:& line-grid + {:project project + :team team + :files files + :create-fn create-file + :limit limit}] + + (when (and (> limit 0) + (> file-count limit)) + [:button.show-more {:on-click on-nav + :tab-index "0" + :on-key-down (fn [event] + (when (kbd/enter? event) + (on-nav)))} + [:div.placeholder-label + (tr "dashboard.show-all-files")] + [:div.placeholder-icon i/arrow-down]])]))) (def recent-files-ref @@ -332,7 +496,8 @@ (mf/defc projects-section [{:keys [team projects profile default-project-id] :as props}] - (let [projects (->> (vals projects) + (let [new-css-system (mf/use-ctx ctx/new-css-system) + projects (->> (vals projects) (sort-by :modified-at) (reverse)) recent-map (mf/deref recent-files-ref) @@ -382,35 +547,68 @@ (st/emit! (dd/fetch-recent-files team-id) (dd/clear-selected-files))) - (when (seq projects) - [:* - [:& header] + (if new-css-system + (when (seq projects) + [:* + [:& header] - (when team-hero? - [:& team-hero {:team team :close-fn close-banner}]) + (when team-hero? + [:& team-hero {:team team :close-fn close-banner}]) - (when (and (contains? cf/flags :dashboard-templates-section) - (or (not tutorial-viewed?) - (not walkthrough-viewed?))) - [:div.hero-projects - (when (and (not tutorial-viewed?) (:is-default team)) - [:& tutorial-project - {:close-tutorial close-tutorial - :default-project-id default-project-id}]) + (when (and (contains? cf/flags :dashboard-templates-section) + (or (not tutorial-viewed?) + (not walkthrough-viewed?))) + [:div {:class (stl/css :hero-projects)} + (when (and (not tutorial-viewed?) (:is-default team)) + [:& tutorial-project + {:close-tutorial close-tutorial + :default-project-id default-project-id}]) - (when (and (not walkthrough-viewed?) (:is-default team)) - [:& interface-walkthrough - {:close-walkthrough close-walkthrough}])]) + (when (and (not walkthrough-viewed?) (:is-default team)) + [:& interface-walkthrough + {:close-walkthrough close-walkthrough}])]) - [:div.dashboard-container.no-bg.dashboard-projects - (for [{:keys [id] :as project} projects] - (let [files (when recent-map - (->> (vals recent-map) - (filterv #(= id (:project-id %))) - (sort-by :modified-at #(compare %2 %1))))] - [:& project-item {:project project - :team team - :files files - :first? (= project (first projects)) - :key id}]))]]))) + [:div {:class (stl/css :dashboard-container :no-bg :dashboard-projects)} + (for [{:keys [id] :as project} projects] + (let [files (when recent-map + (->> (vals recent-map) + (filterv #(= id (:project-id %))) + (sort-by :modified-at #(compare %2 %1))))] + [:& project-item {:project project + :team team + :files files + :first? (= project (first projects)) + :key id}]))]]) + ;; OLD + (when (seq projects) + [:* + [:& header] + + (when team-hero? + [:& team-hero {:team team :close-fn close-banner}]) + + (when (and (contains? cf/flags :dashboard-templates-section) + (or (not tutorial-viewed?) + (not walkthrough-viewed?))) + [:div.hero-projects + (when (and (not tutorial-viewed?) (:is-default team)) + [:& tutorial-project + {:close-tutorial close-tutorial + :default-project-id default-project-id}]) + + (when (and (not walkthrough-viewed?) (:is-default team)) + [:& interface-walkthrough + {:close-walkthrough close-walkthrough}])]) + + [:div.dashboard-container.no-bg.dashboard-projects + (for [{:keys [id] :as project} projects] + (let [files (when recent-map + (->> (vals recent-map) + (filterv #(= id (:project-id %))) + (sort-by :modified-at #(compare %2 %1))))] + [:& project-item {:project project + :team team + :files files + :first? (= project (first projects)) + :key id}]))]])))) diff --git a/frontend/src/app/main/ui/dashboard/projects.scss b/frontend/src/app/main/ui/dashboard/projects.scss new file mode 100644 index 0000000000..ee5016a711 --- /dev/null +++ b/frontend/src/app/main/ui/dashboard/projects.scss @@ -0,0 +1,909 @@ +@import "common/dependencies/colors"; + +$br3: 3px; +$br8: 8px; +$br6: 6px; +$fs14: 0.875rem; +$fs18: 1.125rem; +$fs22: 1.375rem; +$fs24: 1.5rem; +$fw400: 400; +$fw600: 600; +$fw700: 700; +$lh-088: 0.88; +$lh-115: 1.15; // original $title-lh-sm +$size-1: 0.25rem; +$size-2: 0.5rem; +$size-4: 1rem; +$size-5: 1.5rem; +$size-6: 2rem; + +.dashboard-header { + display: flex; + align-items: center; + justify-content: space-between; + background-color: $color-white; + height: 63px; + padding: $size-1 $size-4 $size-1 $size-2; + position: relative; + z-index: 10; + user-select: none; + &.team { + display: grid; + grid-template-columns: 20% 1fr 20%; + } + + .element-name { + margin-right: $size-2; + } + + .btn-secondary { + flex-shrink: 0; + z-index: 10; + height: 32px; + svg { + height: 16px; + width: 16px; + } + } + + svg { + fill: $color-black; + height: 14px; + margin-right: $size-1; + width: 14px; + } + + nav { + display: flex; + align-items: flex-end; + justify-content: center; + z-index: 1; + + ul { + display: flex; + font-size: $fs14; + justify-content: center; + margin: 0; + } + + li { + a { + display: flex; + align-items: center; + flex-basis: 140px; + border-bottom: 3px solid transparent; + color: $color-gray-30; + height: 40px; + padding: $size-1 $size-5; + font-weight: $fw400; + &:hover { + color: $color-black; + text-decoration: none; + } + } + + &.active { + a { + color: $color-black; + border-color: $color-primary; + } + } + } + } + + .dashboard-title { + display: flex; + align-items: center; + margin-left: 13px; + + h1 { + color: $color-black; + display: flex; + flex-shrink: 0; + font-size: $fs22; + font-weight: $fw600; + z-index: 10; + user-select: all; + } + + .context-menu.is-open { + margin-top: 10px; + } + } + + .icon { + display: flex; + align-items: center; + cursor: pointer; + margin-left: $size-2; + z-index: 10; + + svg { + fill: $color-gray-40; + width: 15px; + height: 15px; + + &:hover { + fill: $color-primary-dark; + } + } + } + + .dashboard-buttons { + display: flex; + justify-content: flex-end; + align-items: center; + } + + .dashboard-header-actions { + display: flex; + } + + .pin-icon { + margin: 0 $size-2 0 $size-5; + background-color: transparent; + border: none; + svg { + fill: $color-gray-20; + } + + &.active { + svg { + fill: $color-gray-50; + } + } + } +} + +.dashboard-header { + background-color: transparent; + .dashboard-title { + h1 { + color: $df-primary; + font-size: 24px; + font-weight: 400; + width: 100%; + text-overflow: ellipsis; + overflow: hidden; + white-space: nowrap; + display: block; + max-width: 700px; + } + } + .icon { + svg { + fill: $df-secondary; + } + } + + // Settings sub-menu + .dashboard-header-options { + li { + a { + font-size: 16px; + color: $df-secondary; + border-color: transparent; + &:hover { + color: $df-primary; + } + } + &.active { + a { + color: $df-primary; + } + } + } + } +} + +.dashboard-container { + background-color: $color-dashboard; + flex: 1 0 0; + margin-right: $size-4; + overflow-y: auto; + width: 100%; + &.dashboard-projects { + user-select: none; + } + &.no-bg { + background-color: transparent; + } + &.dashboard-shared { + width: calc(100vw - 320px); + margin-right: 50px; + } + + &.search { + margin-top: 10px; + } +} + +.dashboard-container { + background-color: transparent; + border-top: 1px solid $db-cuaternary; + + .dashboard-settings { + a { + color: $df-secondary; + } + .form-container { + width: 800px; + margin: 80px auto auto 120px; + form { + width: 468px; + .fields-row { + .custom-input, + .custom-select { + flex-direction: column-reverse; + label { + position: relative; + text-transform: uppercase; + color: $df-primary; + font-size: 11px; + margin-bottom: 12px; + margin-left: -4px; + } + input, + select { + background-color: $db-tertiary; + border-radius: 8px; + border-color: transparent; + color: $df-primary; + padding: 0 15px; + &:focus { + outline: 1px solid $da-primary; + } + ::placeholder { + color: $df-secondary; + } + } + .help-icon { + bottom: 12px; + top: auto; + svg { + fill: $df-secondary; + } + } + &.disabled { + input { + background-color: $db-primary; + border-color: $db-cuaternary; + color: $df-secondary; + } + } + .input-container { + background-color: $db-tertiary; + border-radius: 8px; + border-color: transparent; + margin-top: 22px; + .main-content { + label { + position: absolute; + top: -24px; + } + span { + color: $df-primary; + } + } + &:focus { + border: 1px solid $da-primary; + } + } + textarea { + border-radius: 8px; + padding: 12px 14px; + background-color: $db-tertiary; + color: $df-primary; + border: none; + &:focus { + outline: 1px solid $da-primary; + } + } + } + } + .field-title { + color: $df-primary; + } + .field-title:not(:first-child) { + margin-top: 64px; + } + + .field-text { + color: $df-secondary; + } + button, + .btn-secondary { + width: 100%; + font-size: 11px; + text-transform: uppercase; + background-color: $db-tertiary; + color: $df-primary; + &:hover { + color: $da-primary; + background-color: $db-cuaternary; + } + } + hr { + display: none; + } + } + .links { + margin-top: 12px; + } + } + } + + //Access tokens + .dashboard-access-tokens { + width: 800px; + margin-left: 120px; + margin-top: 80px; + .access-tokens-hero-container { + background-color: transparent; + .access-tokens-hero { + width: 468px; + flex-direction: column; + gap: 32px; + background-color: transparent; + margin: 0; + padding: 0; + .desc { + background-color: transparent; + width: 100%; + h2 { + color: $df-primary; + font-size: 24px; + font-weight: regular; + margin-bottom: 32px; + } + p { + color: $df-secondary; + margin-bottom: 0; + font-size: 14px; + } + } + button { + width: 100%; + font-size: 11px; + text-transform: uppercase; + background-color: $db-tertiary; + color: $df-primary; + &:hover { + color: $da-primary; + background-color: $db-cuaternary; + } + } + } + } + .dashboard-table { + width: 800px; + .table-rows { + padding-top: 0; + .table-row { + font-size: 14px; + min-height: 40px; + height: fit-content; + .name { + color: $df-primary; + max-width: 480px; + overflow: hidden; + text-overflow: ellipsis; + display: -webkit-box; + -webkit-line-clamp: 2; + -webkit-box-orient: vertical; + } + .expiration-date { + color: $df-secondary; + } + } + } + } + .access-tokens-empty { + width: 468px; + border: 1px solid $db-cuaternary; + border-radius: 8px; + margin-top: 32px; + font-size: 14px; + background-color: transparent; + color: $df-secondary; + } + } + + // Team webhooks + &.dashboard-team-webhooks { + width: 800px; + margin-left: 120px; + margin-top: 80px; + border: none; + align-items: flex-start; + .webhooks-hero-container { + width: 468px; + background-color: transparent; + .webhooks-hero { + width: 468px; + flex-direction: column; + gap: 32px; + background-color: transparent; + margin: 0; + padding: 0; + .desc { + background-color: transparent; + width: 100%; + h2 { + color: $df-primary; + font-size: 24px; + font-weight: regular; + margin-bottom: 32px; + } + p { + color: $df-secondary; + margin-bottom: 0; + font-size: 14px; + } + } + .btn-primary { + width: 100%; + font-size: 11px; + text-transform: uppercase; + background-color: $db-tertiary; + color: $df-primary; + &:hover { + color: $da-primary; + background-color: $db-cuaternary; + } + } + } + } + .dashboard-table { + width: 800px; + .table-rows { + padding-top: 0; + .table-row { + font-size: 14px; + min-height: 40px; + height: fit-content; + .name { + color: $df-primary; + max-width: 480px; + } + .expiration-date { + color: $df-secondary; + } + } + } + } + .webhooks-empty { + width: 468px; + border: 1px solid $db-cuaternary; + border-radius: 8px; + margin-top: 32px; + font-size: 14px; + background-color: transparent; + color: $df-secondary; + } + } + + // Members section + .dashboard-table { + .table-header { + background-color: transparent; + color: $df-secondary; + font-size: 12px; + text-transform: uppercase; + } + .table-rows { + .table-row { + background-color: $db-tertiary; + border-radius: 8px; + color: $df-primary; + .rol-selector { + background-color: $db-cuaternary; + border-color: transparent; + border-radius: 8px; + } + } + } + .member-info { + .member-name .you, + .member-email { + color: $df-secondary; + } + } + .status-badge { + border-radius: 8px; + color: $db-primary; + text-transform: uppercase; + } + .empty-invitations { + border: 1px solid $db-cuaternary; + border-radius: 8px; + color: $df-secondary; + } + } + .actions-dropdown, + .options-dropdown { + background-color: $db-tertiary; + border: 1px solid $db-cuaternary; + border-radius: 8px; + min-width: 252px; + + .separator { + border-color: transparent; + margin-top: 10px; + } + + li { + border-radius: 8px; + height: 40px; + margin: 5px; + color: $df-primary; + + &:hover { + background-color: $db-cuaternary; + } + } + + &.options-dropdown { + li { + color: $df-primary; + &.warning { + color: $color-danger; + } + } + } + } +} + +.dashboard-project-row { + margin-bottom: $size-5; + position: relative; + + .project { + align-items: center; + background: $color-white; + border-radius: $br3; + display: flex; + flex-direction: row; + justify-content: space-between; + align-items: center; + margin-top: $size-4; + padding: $size-2 $size-2 $size-2 $size-4; + width: 99%; + max-height: 40px; + gap: $size-2; + .project-name-wrapper { + display: flex; + align-items: center; + justify-content: flex-start; + min-height: 32px; + margin-left: $size-2; + } + .show-more { + align-items: center; + color: $color-gray-30; + display: flex; + font-size: $fs14; + justify-content: space-between; + cursor: pointer; + background-color: transparent; + border: none; + .placeholder-icon { + transform: rotate(-90deg); + margin-left: 10px; + svg { + height: 14px; + width: 14px; + fill: $color-gray-30; + } + } + &:hover { + color: $color-primary-dark; + svg { + fill: $color-primary-dark; + } + } + } + + .btn-secondary { + border: none; + padding: $size-2; + } + + h2 { + cursor: pointer; + font-size: $fs18; + line-height: $lh-088; // Original value was 1rem = 16px; 16px/18px = 88.88888% => $lh-088 + font-weight: $fw600; + color: $color-black; + margin-right: $size-1; + } + + .edit-wrapper { + margin-right: $size-4; + } + + .info { + font-size: $fs14; + line-height: $lh-115; // Original value was 1rem = 16px; 16px/14px = 114.285714286% => $lh-115 (rounded) + font-weight: $fw400; + color: $color-gray-60; + margin-left: 0.75rem; + @media (max-width: 760px) { + display: none; + } + } + + .project-actions { + display: flex; + opacity: 1; + margin-left: $size-6; + + .btn-small { + height: 32px; + margin: 0 $size-2; + width: 32px; + svg { + height: 16px; + width: 16px; + } + } + } + + .pin-icon { + cursor: pointer; + display: flex; + align-items: center; + margin-right: 14px; + background-color: transparent; + border: none; + svg { + width: 15px; + height: 15px; + fill: $color-gray-20; + } + + &.active { + svg { + fill: $color-gray-50; + } + } + } + } + + &:hover, + &:focus, + &:focus-within { + .project-actions { + opacity: 1; + } + } + + .show-more { + align-items: center; + color: $color-gray-30; + display: flex; + font-size: $fs14; + justify-content: space-between; + cursor: pointer; + background-color: transparent; + border: none; + position: absolute; + top: 9px; + right: 53px; + .placeholder-icon { + transform: rotate(-90deg); + margin-left: 10px; + svg { + height: 14px; + width: 14px; + fill: $color-gray-30; + } + } + &:hover { + color: $color-primary-dark; + svg { + fill: $color-primary-dark; + } + } + } +} + +.dashboard-project-row .project { + background-color: transparent; + + h2 { + color: $df-primary; + font-weight: 400; + } + span, + .info { + color: $df-secondary; + } + .project-actions { + svg { + fill: $df-primary; + } + .pin-icon svg { + fill: $df-secondary; + } + } +} + +.team-hero { + display: flex; + position: relative; + border: 2px solid $color-gray-10; + border-radius: $br8; + padding: 20px; + margin: 0 1rem 0 21px; + height: 154px; + + .text { + flex-grow: 1; + padding-left: 20px; + .title { + font-size: $fs24; + font-weight: $fw700; + color: $color-black; + } + .info { + span { + color: $color-gray-30; + display: block; + } + padding-top: 10px; + } + } + .close { + position: absolute; + top: 20px; + right: 20px; + background-color: transparent; + border: none; + cursor: pointer; + svg { + transform: rotate(45deg); + width: 16px; + height: 16px; + } + } + .invite { + align-self: flex-end; + height: 40px; + font-family: "worksans", sans-serif; + width: 180px; + } + img { + width: 274px; + margin-bottom: -19px; + @media (max-width: 1200px) { + display: none; + width: 0; + } + } +} + +.hero-projects { + display: grid; + grid-template-columns: 1fr 1fr; + grid-gap: 30px; + margin: 0 1rem 1rem 1.2rem; + .tutorial, + .walkthrough { + display: grid; + grid-template-columns: 1fr 1fr; + position: relative; + border: 2px solid $color-gray-10; + border-radius: $br8; + min-height: 211px; + + .thumbnail { + border-top-left-radius: $br6; + border-bottom-left-radius: $br6; + padding: 30px; + display: block; + background-color: #e0e4e9; + } + + .text { + padding: 30px; + .title { + color: $color-black; + font-size: $fs24; + font-weight: $fw700; + margin-bottom: 8px; + } + .info { + color: $color-gray-50; + margin-bottom: 20px; + font-size: $fs14; + } + } + .action { + font-family: "worksans", sans-serif; + width: 180px; + height: 40px; + } + .close { + position: absolute; + top: 0; + right: 0; + width: $size-5; + cursor: pointer; + display: flex; + margin: 20px; + justify-content: center; + align-items: center; + background-color: transparent; + border: none; + .icon { + svg { + fill: $color-gray-30; + height: 16px; + width: 16px; + transform: rotate(45deg); + &:hover { + fill: $color-primary; + } + } + } + } + + @media (max-width: 1846px) { + grid-template-columns: 190px 1fr; + } + @media (max-width: 1526px) { + grid-template-columns: 1fr; + .img { + display: none; + width: 0; + } + } + } + .walkthrough { + .thumbnail { + background-image: url("/images/walkthrough-cover.png"); + background-position: center; + background-repeat: no-repeat; + background-size: cover; + } + } + .tutorial { + .thumbnail { + background-image: url("/images/hands-on-tutorial.png"); + background-position: center; + background-repeat: no-repeat; + background-size: cover; + } + .loader { + display: flex; + svg#loader-pencil { + width: 31px; + } + } + } +} + +.btn-secondary { + background-color: $db-tertiary; + text-transform: uppercase; + border: none; + color: $df-primary; + border-radius: 8px; + + font-size: 0.75rem; + padding: 0 1rem; + cursor: pointer; + display: flex; + justify-content: center; + align-items: center; + + &:hover { + background-color: $db-cuaternary; + color: $da-primary; + svg { + fill: $da-primary; + } + } +} diff --git a/frontend/src/app/main/ui/dashboard/search.cljs b/frontend/src/app/main/ui/dashboard/search.cljs index 97644bcbca..ad9f517bf3 100644 --- a/frontend/src/app/main/ui/dashboard/search.cljs +++ b/frontend/src/app/main/ui/dashboard/search.cljs @@ -5,10 +5,12 @@ ;; Copyright (c) KALEIDOS INC (ns app.main.ui.dashboard.search + (:require-macros [app.main.style :as stl]) (:require [app.main.data.dashboard :as dd] [app.main.refs :as refs] [app.main.store :as st] + [app.main.ui.context :as ctx] [app.main.ui.dashboard.grid :refer [grid]] [app.main.ui.hooks :as hooks] [app.main.ui.icons :as i] @@ -18,48 +20,83 @@ (mf/defc search-page [{:keys [team search-term] :as props}] - - (mf/use-effect - (mf/deps team) - (fn [] - (when team - (let [tname (if (:is-default team) - (tr "dashboard.your-penpot") - (:name team))] - (dom/set-html-title (tr "title.dashboard.search" tname)))))) - - (mf/use-effect - (mf/deps search-term) - (fn [] - (st/emit! (dd/search {:search-term search-term}) - (dd/clear-selected-files)))) - - (let [result (mf/deref refs/dashboard-search-result) + (let [new-css-system (mf/use-ctx ctx/new-css-system) + result (mf/deref refs/dashboard-search-result) [rowref limit] (hooks/use-dynamic-grid-item-width)] - [:* - [:header.dashboard-header - [:div.dashboard-title#dashboard-search-title - [:h1 (tr "dashboard.title-search")]]] - [:section.dashboard-container.search.no-bg {:ref rowref} - (cond - (empty? search-term) - [:div.grid-empty-placeholder.search - [:div.icon i/search] - [:div.text (tr "dashboard.type-something")]] + (mf/use-effect + (mf/deps team) + (fn [] + (when team + (let [tname (if (:is-default team) + (tr "dashboard.your-penpot") + (:name team))] + (dom/set-html-title (tr "title.dashboard.search" tname)))))) + + (mf/use-effect + (mf/deps search-term) + (fn [] + (st/emit! (dd/search {:search-term search-term}) + (dd/clear-selected-files)))) + (if new-css-system + [:* + [:header {:class (stl/css :dashboard-header)} + [:div#dashboard-search-title {:class (stl/css :dashboard-title)} + [:h1 (tr "dashboard.title-search")]]] + + [:section {:class (stl/css :dashboard-container :search :no-bg) + :ref rowref} + (cond + (empty? search-term) + [:div {:class (stl/css :grid-empty-placeholder :search)} + [:div {:class (stl/css :icon)} i/search] + [:div {:class (stl/css :text)} (tr "dashboard.type-something")]] + + (nil? result) + [:div {:class (stl/css :grid-empty-placeholder :search)} + [:div {:class (stl/css :icon)} i/search] + [:div {:class (stl/css :text)} (tr "dashboard.searching-for" search-term)]] + + (empty? result) + [:div {:class (stl/css :grid-empty-placeholder :search)} + [:div {:class (stl/css :icon)} i/search] + [:div {:class (stl/css :text)} (tr "dashboard.no-matches-for" search-term)]] + + :else + [:& grid {:files result + :hide-new? true + :origin :search + :limit limit}])]] + + ;; OLD + [:* + [:header.dashboard-header + [:div.dashboard-title#dashboard-search-title + [:h1 (tr "dashboard.title-search")]]] + + [:section.dashboard-container.search.no-bg {:ref rowref} + (cond + (empty? search-term) + [:div.grid-empty-placeholder.search + [:div.icon i/search] + [:div.text (tr "dashboard.type-something")]] + + (nil? result) + [:div.grid-empty-placeholder.search + [:div.icon i/search] + [:div.text (tr "dashboard.searching-for" search-term)]] + + (empty? result) + [:div.grid-empty-placeholder.search + [:div.icon i/search] + [:div.text (tr "dashboard.no-matches-for" search-term)]] + + :else + [:& grid {:files result + :hide-new? true + :origin :search + :limit limit}])]]))) + - (nil? result) - [:div.grid-empty-placeholder.search - [:div.icon i/search] - [:div.text (tr "dashboard.searching-for" search-term)]] - (empty? result) - [:div.grid-empty-placeholder.search - [:div.icon i/search] - [:div.text (tr "dashboard.no-matches-for" search-term)]] - :else - [:& grid {:files result - :hide-new? true - :origin :search - :limit limit}])]])) diff --git a/frontend/src/app/main/ui/dashboard/search.scss b/frontend/src/app/main/ui/dashboard/search.scss new file mode 100644 index 0000000000..016cd99969 --- /dev/null +++ b/frontend/src/app/main/ui/dashboard/search.scss @@ -0,0 +1,325 @@ +@import "common/dependencies/colors"; + +$br0: 0; +$br3: 3px; +$br8: 8px; +$br6: 6px; +$br12: 12px; +$fs14: 0.875rem; +$fs16: 1rem; +$fs18: 1.125rem; +$fs22: 1.375rem; +$fs24: 1.5rem; +$fw400: 400; +$fw600: 600; +$fw700: 700; +$lh-088: 0.88; +$lh-115: 1.15; // original $title-lh-sm +$size-1: 0.25rem; +$size-2: 0.5rem; +$size-4: 1rem; +$size-5: 1.5rem; +$size-6: 2rem; + +.dashboard-header { + display: flex; + align-items: center; + justify-content: space-between; + background-color: $color-white; + height: 63px; + padding: $size-1 $size-4 $size-1 $size-2; + position: relative; + z-index: 10; + user-select: none; + &.team { + display: grid; + grid-template-columns: 20% 1fr 20%; + } + + .element-name { + margin-right: $size-2; + } + + .btn-secondary { + flex-shrink: 0; + z-index: 10; + height: 32px; + } + + svg { + fill: $color-black; + height: 14px; + margin-right: $size-1; + width: 14px; + } + + nav { + display: flex; + align-items: flex-end; + justify-content: center; + z-index: 1; + + ul { + display: flex; + font-size: $fs14; + justify-content: center; + margin: 0; + } + + li { + a { + display: flex; + align-items: center; + flex-basis: 140px; + border-bottom: 3px solid transparent; + color: $color-gray-30; + height: 40px; + padding: $size-1 $size-5; + font-weight: $fw400; + &:hover { + color: $color-black; + text-decoration: none; + } + } + + &.active { + a { + color: $color-black; + border-color: $color-primary; + } + } + } + } + + .dashboard-title { + display: flex; + align-items: center; + margin-left: 13px; + + h1 { + color: $color-black; + display: flex; + flex-shrink: 0; + font-size: $fs22; + font-weight: $fw600; + z-index: 10; + user-select: all; + } + + .context-menu.is-open { + margin-top: 10px; + } + } + + .icon { + display: flex; + align-items: center; + cursor: pointer; + margin-left: $size-2; + z-index: 10; + + svg { + fill: $color-gray-40; + width: 15px; + height: 15px; + + &:hover { + fill: $color-primary-dark; + } + } + } + + .dashboard-buttons { + display: flex; + justify-content: flex-end; + align-items: center; + } + + .dashboard-header-actions { + display: flex; + } + + .pin-icon { + margin: 0 $size-2 0 $size-5; + background-color: transparent; + border: none; + svg { + fill: $color-gray-20; + } + + &.active { + svg { + fill: $color-gray-50; + } + } + } +} + +.grid-empty-placeholder { + border-radius: $br12; + display: grid; + background-color: rgba(227, 227, 227, 0.3); + padding: 13px; + margin-right: 13px; + height: 230px; + &.loader { + justify-items: center; + } + .icon { + display: flex; + align-items: center; + justify-content: center; + } + &.libs { + background-image: url(/images/ph-left.svg), url(/images/ph-right.svg); + background-position: + 15% bottom, + 85% top; + background-repeat: no-repeat; + align-items: center; + border: 1px dashed #b1b2b5; + border-radius: $br3; + display: flex; + flex-direction: column; + height: 200px; + margin: 1rem; + padding: 3rem; + justify-content: center; + .text { + p { + max-width: 360px; + text-align: center; + font-size: $fs16; + } + } + } + .create-new { + background-color: white; + border: 2px solid $color-gray-10; + border-radius: $br3; + color: $color-black; + cursor: pointer; + height: 158px; + font-family: "worksans", sans-serif; + margin: 0.5rem; + &:hover { + border: 2px solid $color-primary; + } + } + + &.search { + align-items: center; + display: flex; + justify-content: center; + flex-direction: column; + height: 200px; + // background: $color-white; + border: 1px dashed #e3e3e3; + border-radius: $br0; + } + + svg { + width: 36px; + height: 36px; + fill: $color-gray-20; + } + + .text { + margin-top: 10px; + color: $color-gray-30; + font-size: $fs16; + } +} + +.dashboard-container { + background-color: $color-dashboard; + flex: 1 0 0; + margin-right: $size-4; + overflow-y: auto; + width: 100%; + &.dashboard-projects { + user-select: none; + } + &.no-bg { + background-color: transparent; + } + &.dashboard-shared { + width: calc(100vw - 320px); + margin-right: 50px; + } + + &.search { + margin-top: 10px; + } +} + +.dashboard-header { + background-color: transparent; + .dashboard-title { + h1 { + color: $df-primary; + font-size: 24px; + font-weight: 400; + width: 100%; + text-overflow: ellipsis; + overflow: hidden; + white-space: nowrap; + display: block; + max-width: 700px; + } + } + .icon { + svg { + fill: $df-secondary; + } + } + + // Settings sub-menu + .dashboard-header-options { + li { + a { + font-size: 16px; + color: $df-secondary; + border-color: transparent; + &:hover { + color: $df-primary; + } + } + &.active { + a { + color: $df-primary; + } + } + } + } +} + +.grid-empty-placeholder { + background-color: transparent; + + .create-new { + background-color: $db-tertiary; + border-radius: 8px; + border: none; + color: $df-primary; + text-transform: uppercase; + + &:hover { + background-color: $db-cuaternary; + color: $da-primary; + } + } + + &.search { + border: 1px solid $db-cuaternary; + border-radius: 8px; + .text { + color: $df-primary; + } + .icon { + svg { + fill: $df-secondary; + } + } + } +} diff --git a/frontend/src/app/main/ui/dashboard/sidebar.cljs b/frontend/src/app/main/ui/dashboard/sidebar.cljs index e52ad2e71a..71840fed43 100644 --- a/frontend/src/app/main/ui/dashboard/sidebar.cljs +++ b/frontend/src/app/main/ui/dashboard/sidebar.cljs @@ -5,6 +5,7 @@ ;; Copyright (c) KALEIDOS INC (ns app.main.ui.dashboard.sidebar + (:require-macros [app.main.style :as stl]) (:require [app.common.data :as d] [app.common.data.macros :as dm] @@ -19,6 +20,7 @@ [app.main.store :as st] [app.main.ui.components.dropdown-menu :refer [dropdown-menu dropdown-menu-item*]] [app.main.ui.components.link :refer [link]] + [app.main.ui.context :as ctx] [app.main.ui.dashboard.comments :refer [comments-section]] [app.main.ui.dashboard.inline-edition :refer [inline-edition]] [app.main.ui.dashboard.project-menu :refer [project-menu]] @@ -39,7 +41,8 @@ (mf/defc sidebar-project [{:keys [item selected?] :as props}] - (let [dstate (mf/deref refs/dashboard-local) + (let [new-css-system (mf/use-ctx ctx/new-css-system) + dstate (mf/deref refs/dashboard-local) selected-files (:selected-files dstate) selected-project (:selected-project dstate) edit-id (:project-for-edit dstate) @@ -132,32 +135,58 @@ mdata {:on-success on-drop-success}] (st/emit! (dd/move-files (with-meta data mdata)))))))] - [:* - [:li {:tab-index "0" - :class (if selected? "current" - (when (:dragging? @local) "dragging")) - :on-click on-click - :on-key-down on-key-down - :on-double-click on-edit-open - :on-context-menu on-menu-click - :on-drag-enter on-drag-enter - :on-drag-over on-drag-over - :on-drag-leave on-drag-leave - :on-drop on-drop} - (if (:edition? @local) - [:& inline-edition {:content (:name item) - :on-end on-edit}] - [:span.element-title (:name item)])] - [:& project-menu {:project item - :show? (:menu-open @local) - :left (:x (:menu-pos @local)) - :top (:y (:menu-pos @local)) - :on-edit on-edit-open - :on-menu-close on-menu-close}]])) + (if new-css-system + [:* + [:li {:tab-index "0" + :class (if selected? (stl/css :current) + (when (:dragging? @local) (stl/css :dragging))) + :on-click on-click + :on-key-down on-key-down + :on-double-click on-edit-open + :on-context-menu on-menu-click + :on-drag-enter on-drag-enter + :on-drag-over on-drag-over + :on-drag-leave on-drag-leave + :on-drop on-drop} + (if (:edition? @local) + [:& inline-edition {:content (:name item) + :on-end on-edit}] + [:span {:class (stl/css :element-title)} (:name item)])] + [:& project-menu {:project item + :show? (:menu-open @local) + :left (:x (:menu-pos @local)) + :top (:y (:menu-pos @local)) + :on-edit on-edit-open + :on-menu-close on-menu-close}]] + + ;; OLD + [:* + [:li {:tab-index "0" + :class (if selected? "current" + (when (:dragging? @local) "dragging")) + :on-click on-click + :on-key-down on-key-down + :on-double-click on-edit-open + :on-context-menu on-menu-click + :on-drag-enter on-drag-enter + :on-drag-over on-drag-over + :on-drag-leave on-drag-leave + :on-drop on-drop} + (if (:edition? @local) + [:& inline-edition {:content (:name item) + :on-end on-edit}] + [:span.element-title (:name item)])] + [:& project-menu {:project item + :show? (:menu-open @local) + :left (:x (:menu-pos @local)) + :top (:y (:menu-pos @local)) + :on-edit on-edit-open + :on-menu-close on-menu-close}]]))) (mf/defc sidebar-search [{:keys [search-term team-id] :as props}] - (let [search-term (or search-term "") + (let [new-css-system (mf/use-ctx ctx/new-css-system) + search-term (or search-term "") focused? (mf/use-state false) emit! (mf/use-memo #(f/debounce st/emit! 500)) @@ -198,38 +227,72 @@ (dom/prevent-default e) (dom/stop-propagation e))))] - [:form.sidebar-search - [:input.input-text - {:key "images-search-box" - :id "search-input" - :type "text" - :aria-label (tr "dashboard.search-placeholder") - :placeholder (tr "dashboard.search-placeholder") - :default-value search-term - :auto-complete "off" - ;; :on-focus on-search-focus - :on-blur on-search-blur - :on-change on-search-change - :on-key-press on-key-press - :ref #(when % (set! (.-value %) search-term))}] + (if new-css-system + [:form {:class (stl/css :sidebar-search)} + [:input + {:class (stl/css :input-text) + :key "images-search-box" + :id "search-input" + :type "text" + :aria-label (tr "dashboard.search-placeholder") + :placeholder (tr "dashboard.search-placeholder") + :default-value search-term + :auto-complete "off" + ;; :on-focus on-search-focus + :on-blur on-search-blur + :on-change on-search-change + :on-key-press on-key-press + :ref #(when % (set! (.-value %) search-term))}] - (if (or @focused? (seq search-term)) - [:div.clear-search - {:tab-index "0" - :on-click on-clear-click - :on-key-down (fn [event] - (when (kbd/enter? event) - (on-clear-click event)))} - i/close] + (if (or @focused? (seq search-term)) + [:div + {:class (stl/css :clear-search) + :tab-index "0" + :on-click on-clear-click + :on-key-down (fn [event] + (when (kbd/enter? event) + (on-clear-click event)))} + i/close] - [:div.search - {:on-click on-clear-click} - i/search])])) + [:div + {:class (stl/css :search) + :on-click on-clear-click} + i/search])] + + ;; OLD + [:form.sidebar-search + [:input.input-text + {:key "images-search-box" + :id "search-input" + :type "text" + :aria-label (tr "dashboard.search-placeholder") + :placeholder (tr "dashboard.search-placeholder") + :default-value search-term + :auto-complete "off" + ;; :on-focus on-search-focus + :on-blur on-search-blur + :on-change on-search-change + :on-key-press on-key-press + :ref #(when % (set! (.-value %) search-term))}] + + (if (or @focused? (seq search-term)) + [:div.clear-search + {:tab-index "0" + :on-click on-clear-click + :on-key-down (fn [event] + (when (kbd/enter? event) + (on-clear-click event)))} + i/close] + + [:div.search + {:on-click on-clear-click} + i/search])]))) (mf/defc teams-selector-dropdown-items {::mf/wrap-props false} [{:keys [team profile teams] :as props}] - (let [on-create-clicked + (let [new-css-system (mf/use-ctx ctx/new-css-system) + on-create-clicked (mf/use-callback #(st/emit! (modal/show :team-form {}))) @@ -238,41 +301,80 @@ (fn [team-id] (st/emit! (dd/go-to-projects team-id))))] - [:* - [:> dropdown-menu-item* {:on-click (partial team-selected (:default-team-id profile)) - :on-key-down (fn [event] - (when (kbd/enter? event) - (team-selected (:default-team-id profile) event))) - :id "teams-selector-default-team" - :class "team-name"} - [:span.team-icon i/logo-icon] - [:span.team-text (tr "dashboard.your-penpot")] - (when (= (:default-team-id profile) (:id team)) - [:span.icon i/tick])] - - (for [team-item (remove :is-default (vals teams))] - [:> dropdown-menu-item* {:on-click (partial team-selected (:id team-item)) + (if new-css-system + [:* + [:> dropdown-menu-item* {:on-click (partial team-selected (:default-team-id profile)) :on-key-down (fn [event] (when (kbd/enter? event) - (team-selected (:id team-item) event))) - :id (str "teams-selector-" (:id team-item)) - :class "team-name" - :key (str "teams-selector-" (:id team-item))} - [:span.team-icon - [:img {:src (cf/resolve-team-photo-url team-item) - :alt (:name team-item)}]] - [:span.team-text {:title (:name team-item)} (:name team-item)] - (when (= (:id team-item) (:id team)) - [:span.icon i/tick])]) - [:hr {:role "separator"}] - [:> dropdown-menu-item* {:on-click on-create-clicked - :on-key-down (fn [event] - (when (kbd/enter? event) - (on-create-clicked event))) - :id "teams-selector-create-team" - :class "team-name action"} - [:span.team-icon.new-team i/close] - [:span.team-text (tr "dashboard.create-new-team")]]])) + (team-selected (:default-team-id profile) event))) + :id "teams-selector-default-team" + :class (stl/css :team-name)} + [:span {:class (stl/css :team-icon)} i/logo-icon] + [:span {:class (stl/css :team-text)} (tr "dashboard.your-penpot")] + (when (= (:default-team-id profile) (:id team)) + [:span {:class (stl/css :icon)} i/tick])] + + (for [team-item (remove :is-default (vals teams))] + [:> dropdown-menu-item* {:on-click (partial team-selected (:id team-item)) + :on-key-down (fn [event] + (when (kbd/enter? event) + (team-selected (:id team-item) event))) + :id (str "teams-selector-" (:id team-item)) + :class (stl/css :team-name) + :key (str "teams-selector-" (:id team-item))} + [:span {:class (stl/css :team-icon)} + [:img {:src (cf/resolve-team-photo-url team-item) + :alt (:name team-item)}]] + [:span {:class (stl/css :team-text) + :title (:name team-item)} (:name team-item)] + (when (= (:id team-item) (:id team)) + [:span {:class (stl/css :icon)} i/tick])]) + [:hr {:role "separator"}] + [:> dropdown-menu-item* {:on-click on-create-clicked + :on-key-down (fn [event] + (when (kbd/enter? event) + (on-create-clicked event))) + :id "teams-selector-create-team" + :class (stl/css :team-name :action)} + [:span {:class (stl/css :team-icon :new-team)} i/close] + [:span {:class (stl/css :team-text)} (tr "dashboard.create-new-team")]]] + + ;; OLD + [:* + [:> dropdown-menu-item* {:on-click (partial team-selected (:default-team-id profile)) + :on-key-down (fn [event] + (when (kbd/enter? event) + (team-selected (:default-team-id profile) event))) + :id "teams-selector-default-team" + :class "team-name"} + [:span.team-icon i/logo-icon] + [:span.team-text (tr "dashboard.your-penpot")] + (when (= (:default-team-id profile) (:id team)) + [:span.icon i/tick])] + + (for [team-item (remove :is-default (vals teams))] + [:> dropdown-menu-item* {:on-click (partial team-selected (:id team-item)) + :on-key-down (fn [event] + (when (kbd/enter? event) + (team-selected (:id team-item) event))) + :id (str "teams-selector-" (:id team-item)) + :class "team-name" + :key (str "teams-selector-" (:id team-item))} + [:span.team-icon + [:img {:src (cf/resolve-team-photo-url team-item) + :alt (:name team-item)}]] + [:span.team-text {:title (:name team-item)} (:name team-item)] + (when (= (:id team-item) (:id team)) + [:span.icon i/tick])]) + [:hr {:role "separator"}] + [:> dropdown-menu-item* {:on-click on-create-clicked + :on-key-down (fn [event] + (when (kbd/enter? event) + (on-create-clicked event))) + :id "teams-selector-create-team" + :class "team-name action"} + [:span.team-icon.new-team i/close] + [:span.team-text (tr "dashboard.create-new-team")]]]))) (s/def ::member-id ::us/uuid) (s/def ::leave-modal-form @@ -280,7 +382,8 @@ (mf/defc team-options-dropdown [{:keys [team profile] :as props}] - (let [go-members #(st/emit! (dd/go-to-team-members)) + (let [new-css-system (mf/use-ctx ctx/new-css-system) + go-members #(st/emit! (dd/go-to-team-members)) go-invitations #(st/emit! (dd/go-to-team-invitations)) go-webhooks #(st/emit! (dd/go-to-team-webhooks)) go-settings #(st/emit! (dd/go-to-team-settings)) @@ -433,14 +536,15 @@ (when (kbd/enter? event) (on-delete-clicked))) :id "teams-options-delete-team" - :class "warning" + :class (if new-css-system (stl/css :warning) "warning") :data-test "delete-team"} (tr "dashboard.delete-team")])])) (mf/defc sidebar-team-switch [{:keys [team profile] :as props}] - (let [teams (mf/deref refs/teams) + (let [new-css-system (mf/use-ctx ctx/new-css-system) + teams (mf/deref refs/teams) teams-without-default (into {} (filter (fn [[_ v]] (= false (:is-default v))) teams)) team-ids (map #(str "teams-selector-" %) (keys teams-without-default)) ids (concat ["teams-selector-default-team"] team-ids ["teams-selector-create-team"]) @@ -458,70 +562,141 @@ (when (get-in team [:permissions :is-owner]) "teams-options-delete-team")]] - [:div.sidebar-team-switch - [:div.switch-content - [:button.current-team {:tab-index "0" - :on-click (fn [event] - (dom/stop-propagation event) - (reset! show-teams-ddwn? true)) - :on-key-down (fn [event] - (when (or (kbd/space? event) (kbd/enter? event)) - (dom/prevent-default event) - (reset! show-teams-ddwn? true) - (ts/schedule-on-idle - (fn [] - (let [first-element (dom/get-element (first ids))] - (when first-element - (dom/focus! first-element)))))))} - (if (:is-default team) - [:div.team-name - [:span.team-icon i/logo-icon] - [:span.team-text (tr "dashboard.default-team-name")]] - [:div.team-name - [:span.team-icon - [:img {:src (cf/resolve-team-photo-url team) - :alt (:name team)}]] - [:span.team-text {:title (:name team)} (:name team)]]) + (if new-css-system + [:div {:class (stl/css :sidebar-team-switch)} + [:div {:class (stl/css :switch-content)} + [:button + {:class (stl/css :current-team) + :tab-index "0" + :on-click + (fn [event] + (dom/stop-propagation event) + (reset! show-teams-ddwn? true)) - [:span.switch-icon - i/arrow-down]] + :on-key-down + (fn [event] + (when (or (kbd/space? event) (kbd/enter? event)) + (dom/prevent-default event) + (reset! show-teams-ddwn? true) + (ts/schedule-on-idle + (fn [] + (let [first-element (dom/get-element (first ids))] + (when first-element + (dom/focus! first-element)))))))} - (when-not (:is-default team) - [:button.switch-options {:on-click (fn [event] - (dom/stop-propagation event) - (reset! show-team-opts-ddwn? true)) - :tab-index "0" - :on-key-down (fn [event] - (when (or (kbd/space? event) (kbd/enter? event)) - (dom/prevent-default event) - (reset! show-team-opts-ddwn? true) - (ts/schedule-on-idle - (fn [] - (let [first-element (dom/get-element (first options-ids))] - (when first-element - (dom/focus! first-element)))))))} - i/actions])] + (if (:is-default team) + [:div {:class (stl/css :team-name)} + [:span {:class (stl/css :team-icon)} i/logo-icon] + [:span {:class (stl/css :team-text)} (tr "dashboard.default-team-name")]] + [:div {:class (stl/css :team-name)} + [:span {:class (stl/css :team-icon)} + [:img {:src (cf/resolve-team-photo-url team) + :alt (:name team)}]] + [:span {:class (stl/css :team-text) :title (:name team)} (:name team)]]) - ;; Teams Dropdown - [:& dropdown-menu {:show @show-teams-ddwn? - :on-close #(reset! show-teams-ddwn? false) - :ids ids - :list-class "dropdown teams-dropdown"} - [:& teams-selector-dropdown-items {:ids ids - :team team - :profile profile - :teams teams}]] + [:span {:class (stl/css :switch-icon)} i/arrow-down]] - [:& dropdown-menu {:show @show-team-opts-ddwn? - :on-close #(reset! show-team-opts-ddwn? false) - :ids options-ids - :list-class "dropdown options-dropdown"} - [:& team-options-dropdown {:team team - :profile profile}]]])) + (when-not (:is-default team) + [:button + {:class (stl/css :switch-options) + :on-click (fn [event] + (dom/stop-propagation event) + (reset! show-team-opts-ddwn? true)) + :tab-index "0" + :on-key-down (fn [event] + (when (or (kbd/space? event) (kbd/enter? event)) + (dom/prevent-default event) + (reset! show-team-opts-ddwn? true) + (ts/schedule-on-idle + (fn [] + (let [first-element (dom/get-element (first options-ids))] + (when first-element + (dom/focus! first-element)))))))} + i/actions])] + + ;; Teams Dropdown + [:& dropdown-menu {:show @show-teams-ddwn? + :on-close #(reset! show-teams-ddwn? false) + :ids ids + :list-class (stl/css :dropdown :teams-dropdown)} + [:& teams-selector-dropdown-items {:ids ids + :team team + :profile profile + :teams teams}]] + + [:& dropdown-menu {:show @show-team-opts-ddwn? + :on-close #(reset! show-team-opts-ddwn? false) + :ids options-ids + :list-class (stl/css :dropdown :options-dropdown)} + [:& team-options-dropdown {:team team + :profile profile}]]] + + ;; Old css + [:div.sidebar-team-switch + [:div.switch-content + [:button.current-team {:tab-index "0" + :on-click (fn [event] + (dom/stop-propagation event) + (reset! show-teams-ddwn? true)) + :on-key-down (fn [event] + (when (or (kbd/space? event) (kbd/enter? event)) + (dom/prevent-default event) + (reset! show-teams-ddwn? true) + (ts/schedule-on-idle + (fn [] + (let [first-element (dom/get-element (first ids))] + (when first-element + (dom/focus! first-element)))))))} + (if (:is-default team) + [:div.team-name + [:span.team-icon i/logo-icon] + [:span.team-text (tr "dashboard.default-team-name")]] + [:div.team-name + [:span.team-icon + [:img {:src (cf/resolve-team-photo-url team) + :alt (:name team)}]] + [:span.team-text {:title (:name team)} (:name team)]]) + + [:span.switch-icon + i/arrow-down]] + + (when-not (:is-default team) + [:button.switch-options {:on-click (fn [event] + (dom/stop-propagation event) + (reset! show-team-opts-ddwn? true)) + :tab-index "0" + :on-key-down (fn [event] + (when (or (kbd/space? event) (kbd/enter? event)) + (dom/prevent-default event) + (reset! show-team-opts-ddwn? true) + (ts/schedule-on-idle + (fn [] + (let [first-element (dom/get-element (first options-ids))] + (when first-element + (dom/focus! first-element)))))))} + i/actions])] + + ;; Teams Dropdown + [:& dropdown-menu {:show @show-teams-ddwn? + :on-close #(reset! show-teams-ddwn? false) + :ids ids + :list-class "dropdown teams-dropdown"} + [:& teams-selector-dropdown-items {:ids ids + :team team + :profile profile + :teams teams}]] + + [:& dropdown-menu {:show @show-team-opts-ddwn? + :on-close #(reset! show-team-opts-ddwn? false) + :ids options-ids + :list-class "dropdown options-dropdown"} + [:& team-options-dropdown {:team team + :profile profile}]]]))) (mf/defc sidebar-content [{:keys [projects profile section team project search-term] :as props}] - (let [default-project-id + (let [new-css-system (mf/use-ctx ctx/new-css-system) + default-project-id (->> (vals projects) (d/seek :is-default) (:id)) @@ -607,60 +782,115 @@ (remove :is-default) (filter :is-pinned))] - [:div.sidebar-content - [:& sidebar-team-switch {:team team :profile profile}] - [:hr] - [:& sidebar-search {:search-term search-term - :team-id (:id team)}] - [:div.sidebar-content-section - [:ul.sidebar-nav.no-overflow - [:li.recent-projects - {:class-name (when projects? "current")} - [:& link {:action go-projects - :keyboard-action go-projects-with-key} - [:span.element-title (tr "labels.projects")]]] + (if new-css-system + [:div {:class (stl/css :sidebar-content)} + [:& sidebar-team-switch {:team team :profile profile}] + [:hr] + [:& sidebar-search {:search-term search-term + :team-id (:id team)}] - [:li {:class-name (when drafts? "current")} - [:& link {:action go-drafts - :keyboard-action go-drafts-with-key} - [:span.element-title (tr "labels.drafts")]]] + [:div {:class (stl/css :sidebar-content-section)} + [:ul {:class (stl/css :sidebar-nav :no-overflow)} + [:li + {:class (stl/css :recent-projects) + :class-name (when projects? (stl/css :current))} + [:& link {:action go-projects + :keyboard-action go-projects-with-key} + [:span {:class (stl/css :element-title)} (tr "labels.projects")]]] + + [:li {:class-name (when drafts? (stl/css :current))} + [:& link {:action go-drafts + :keyboard-action go-drafts-with-key} + [:span {:class (stl/css :element-title)} (tr "labels.drafts")]]] - [:li {:class-name (when libs? "current")} - [:& link {:action go-libs - :keyboard-action go-libs-with-key} - [:span.element-title (tr "labels.shared-libraries")]]]]] + [:li {:class-name (when libs? (stl/css :current))} + [:& link {:action go-libs + :keyboard-action go-libs-with-key} + [:span {:class (stl/css :element-title)} (tr "labels.shared-libraries")]]]]] - [:hr] + [:hr] - [:div.sidebar-content-section - [:ul.sidebar-nav.no-overflow - [:li {:class-name (when fonts? "current")} + [:div {:class (stl/css :sidebar-content-section)} + [:ul {:class (stl/css :sidebar-nav :no-overflow)} + [:li {:class-name (when fonts? (stl/css :current))} + [:& link {:action go-fonts + :keyboard-action go-fonts-with-key + :data-test "fonts"} + [:span {:class (stl/css :element-title)} (tr "labels.fonts")]]]]] - [:& link {:action go-fonts - :keyboard-action go-fonts-with-key - :data-test "fonts"} - [:span.element-title (tr "labels.fonts")]]]]] + [:hr] + [:div {:class (stl/css :sidebar-content-section) + :data-test "pinned-projects"} + (if (seq pinned-projects) + [:ul {:class (stl/css :sidebar-nav)} + (for [item pinned-projects] + [:& sidebar-project + {:item item + :key (dm/str (:id item)) + :id (:id item) + :team-id (:id team) + :selected? (= (:id item) (:id project))}])] + [:div {:class (stl/css :sidebar-empty-placeholder)} + [:span {:class (stl/css :icon)} i/pin] + [:span {:class (stl/css :text)} (tr "dashboard.no-projects-placeholder")]])]] - [:hr] - [:div.sidebar-content-section {:data-test "pinned-projects"} - (if (seq pinned-projects) - [:ul.sidebar-nav - (for [item pinned-projects] - [:& sidebar-project - {:item item - :key (dm/str (:id item)) - :id (:id item) - :team-id (:id team) - :selected? (= (:id item) (:id project))}])] - [:div.sidebar-empty-placeholder - [:span.icon i/pin] - [:span.text (tr "dashboard.no-projects-placeholder")]])]])) + ;; OLD STYLES + [:div.sidebar-content + [:& sidebar-team-switch {:team team :profile profile}] + [:hr] + [:& sidebar-search {:search-term search-term + :team-id (:id team)}] + [:div.sidebar-content-section + [:ul.sidebar-nav.no-overflow + [:li.recent-projects + {:class-name (when projects? "current")} + [:& link {:action go-projects + :keyboard-action go-projects-with-key} + [:span.element-title (tr "labels.projects")]]] + + [:li {:class-name (when drafts? "current")} + [:& link {:action go-drafts + :keyboard-action go-drafts-with-key} + [:span.element-title (tr "labels.drafts")]]] + + + [:li {:class-name (when libs? "current")} + [:& link {:action go-libs + :keyboard-action go-libs-with-key} + [:span.element-title (tr "labels.shared-libraries")]]]]] + + [:hr] + + [:div.sidebar-content-section + [:ul.sidebar-nav.no-overflow + [:li {:class-name (when fonts? "current")} + + [:& link {:action go-fonts + :keyboard-action go-fonts-with-key + :data-test "fonts"} + [:span.element-title (tr "labels.fonts")]]]]] + + [:hr] + [:div.sidebar-content-section {:data-test "pinned-projects"} + (if (seq pinned-projects) + [:ul.sidebar-nav + (for [item pinned-projects] + [:& sidebar-project + {:item item + :key (dm/str (:id item)) + :id (:id item) + :team-id (:id team) + :selected? (= (:id item) (:id project))}])] + [:div.sidebar-empty-placeholder + [:span.icon i/pin] + [:span.text (tr "dashboard.no-projects-placeholder")]])]]))) (mf/defc profile-section [{:keys [profile team] :as props}] - (let [show (mf/use-state false) + (let [new-css-system (mf/use-ctx ctx/new-css-system) + show (mf/use-state false) photo (cf/resolve-profile-photo-url profile) on-click @@ -681,127 +911,242 @@ (st/emit! (modal/show {:type :onboarding})) (st/emit! (modal/show {:type :release-notes :version version}))))))] - [:div.profile-section - [:div.profile {:tab-index "0" - :on-click (fn [event] - (dom/stop-propagation event) - (reset! show true)) - :on-key-down (fn [event] - (when (kbd/enter? event) - (reset! show true))) - :data-test "profile-btn"} - [:img {:src photo - :alt (:fullname profile)}] - [:span (:fullname profile)]] - - [:& dropdown-menu {:on-close (fn [event] - (dom/stop-propagation event) - (reset! show false)) - :show @show} - [:ul.dropdown - [:li {:tab-index (if show - "0" - "-1") - :on-click (partial on-click :settings-profile) - :on-key-down (fn [event] - (when (kbd/enter? event) - (on-click :settings-profile event))) - :data-test "profile-profile-opt"} - [:span.text (tr "labels.your-account")]] - [:li.separator {:tab-index (if show - "0" - "-1") - :on-click #(dom/open-new-window "https://help.penpot.app") - :on-key-down (fn [event] - (when (kbd/enter? event) - (dom/open-new-window "https://help.penpot.app"))) - :data-test "help-center-profile-opt"} - [:span.text (tr "labels.help-center")]] - [:li {:tab-index (if show - "0" - "-1") - :on-click #(dom/open-new-window "https://community.penpot.app") - :on-key-down (fn [event] - (when (kbd/enter? event) - (dom/open-new-window "https://community.penpot.app")))} - [:span.text (tr "labels.community")]] - [:li {:tab-index (if show - "0" - "-1") - :on-click #(dom/open-new-window "https://www.youtube.com/c/Penpot") - :on-key-down (fn [event] - (when (kbd/enter? event) - (dom/open-new-window "https://www.youtube.com/c/Penpot")))} - [:span.text (tr "labels.tutorials")]] - [:li {:tab-index (if show - "0" - "-1") - :on-click show-release-notes - :on-key-down (fn [event] - (when (kbd/enter? event) - (show-release-notes)))} - [:span (tr "labels.release-notes")]] - - [:li.separator {:tab-index (if show - "0" - "-1") - :on-click #(dom/open-new-window "https://penpot.app/libraries-templates") - :on-key-down (fn [event] - (when (kbd/enter? event) - (dom/open-new-window "https://penpot.app/libraries-templates"))) - :data-test "libraries-templates-profile-opt"} - [:span.text (tr "labels.libraries-and-templates")]] - [:li {:tab-index (if show - "0" - "-1") - :on-click #(dom/open-new-window "https://github.com/penpot/penpot") - :on-key-down (fn [event] - (when (kbd/enter? event) - (dom/open-new-window "https://github.com/penpot/penpot")))} - [:span (tr "labels.github-repo")]] - [:li {:tab-index (if show - "0" - "-1") - :on-click #(dom/open-new-window "https://penpot.app/terms") + (if new-css-system + [:div {:class (stl/css :profile-section)} + [:div {:class (stl/css :profile) + :tab-index "0" + :on-click (fn [event] + (dom/stop-propagation event) + (reset! show true)) :on-key-down (fn [event] (when (kbd/enter? event) - (dom/open-new-window "https://penpot.app/terms")))} - [:span (tr "auth.terms-of-service")]] + (reset! show true))) + :data-test "profile-btn"} + [:img {:src photo + :alt (:fullname profile)}] + [:span (:fullname profile)]] - (when (contains? cf/flags :user-feedback) + [:& dropdown-menu {:on-close (fn [event] + (dom/stop-propagation event) + (reset! show false)) + :show @show} + [:ul {:class (stl/css :dropdown)} + [:li {:tab-index (if show "0" "-1") + :on-click (partial on-click :settings-profile) + :on-key-down (fn [event] + (when (kbd/enter? event) + (on-click :settings-profile event))) + :data-test "profile-profile-opt"} + [:span {:class (stl/css :text)} (tr "labels.your-account")]] + + [:li {:class (stl/css :separator) + :tab-index (if show "0" "-1") + :on-click #(dom/open-new-window "https://help.penpot.app") + :on-key-down (fn [event] + (when (kbd/enter? event) + (dom/open-new-window "https://help.penpot.app"))) + :data-test "help-center-profile-opt"} + [:span {:class (stl/css :text)} (tr "labels.help-center")]] + + [:li {:tab-index (if show "0" "-1") + :on-click #(dom/open-new-window "https://community.penpot.app") + :on-key-down (fn [event] + (when (kbd/enter? event) + (dom/open-new-window "https://community.penpot.app")))} + [:span {:class (stl/css :text)} (tr "labels.community")]] + + [:li {:tab-index (if show "0" "-1") + :on-click #(dom/open-new-window "https://www.youtube.com/c/Penpot") + :on-key-down (fn [event] + (when (kbd/enter? event) + (dom/open-new-window "https://www.youtube.com/c/Penpot")))} + [:span {:class (stl/css :text)} (tr "labels.tutorials")]] + + [:li {:tab-index (if show "0" "-1") + :on-click show-release-notes + :on-key-down (fn [event] + (when (kbd/enter? event) + (show-release-notes)))} + [:span {:class (stl/css :text)} (tr "labels.release-notes")]] + + [:li {:class (stl/css :separator) + :tab-index (if show "0" "-1") + :on-click #(dom/open-new-window "https://penpot.app/libraries-templates") + :on-key-down (fn [event] + (when (kbd/enter? event) + (dom/open-new-window "https://penpot.app/libraries-templates"))) + :data-test "libraries-templates-profile-opt"} + [:span {:class (stl/css :text)} (tr "labels.libraries-and-templates")]] + + [:li {:tab-index (if show "0" "-1") + :on-click #(dom/open-new-window "https://github.com/penpot/penpot") + :on-key-down (fn [event] + (when (kbd/enter? event) + (dom/open-new-window "https://github.com/penpot/penpot")))} + [:span {:class (stl/css :text)} (tr "labels.github-repo")]] + + [:li {:tab-index (if show "0" "-1") + :on-click #(dom/open-new-window "https://penpot.app/terms") + :on-key-down (fn [event] + (when (kbd/enter? event) + (dom/open-new-window "https://penpot.app/terms")))} + [:span {:class (stl/css :text)} (tr "auth.terms-of-service")]] + + (when (contains? cf/flags :user-feedback) + [:li {:class (stl/css :separator) + :tab-index (if show "0" "-1") + :on-click (partial on-click :settings-feedback) + :on-key-down (fn [event] + (when (kbd/enter? event) + (on-click :settings-feedback event))) + :data-test "feedback-profile-opt"} + [:span {:class (stl/css :text)} (tr "labels.give-feedback")]]) + + [:li {:class (stl/css :separator) + :tab-index (if show "0" "-1") + :on-click #(on-click (du/logout) %) + :on-key-down (fn [event] + (when (kbd/enter? event) + (on-click (du/logout) event))) + :data-test "logout-profile-opt"} + [:span {:class (stl/css :icon)} i/exit] + [:span {:class (stl/css :text)} (tr "labels.logout")]]]] + + (when (and team profile) + [:& comments-section {:profile profile + :team team}])] + + ;; OLD + [:div.profile-section + [:div.profile {:tab-index "0" + :on-click (fn [event] + (dom/stop-propagation event) + (reset! show true)) + :on-key-down (fn [event] + (when (kbd/enter? event) + (reset! show true))) + :data-test "profile-btn"} + [:img {:src photo + :alt (:fullname profile)}] + [:span (:fullname profile)]] + + [:& dropdown-menu {:on-close (fn [event] + (dom/stop-propagation event) + (reset! show false)) + :show @show} + [:ul.dropdown + [:li {:tab-index (if show + "0" + "-1") + :on-click (partial on-click :settings-profile) + :on-key-down (fn [event] + (when (kbd/enter? event) + (on-click :settings-profile event))) + :data-test "profile-profile-opt"} + [:span.text (tr "labels.your-account")]] [:li.separator {:tab-index (if show "0" "-1") - :on-click (partial on-click :settings-feedback) + :on-click #(dom/open-new-window "https://help.penpot.app") :on-key-down (fn [event] (when (kbd/enter? event) - (on-click :settings-feedback event))) - :data-test "feedback-profile-opt"} - [:span.text (tr "labels.give-feedback")]]) + (dom/open-new-window "https://help.penpot.app"))) + :data-test "help-center-profile-opt"} + [:span.text (tr "labels.help-center")]] + [:li {:tab-index (if show + "0" + "-1") + :on-click #(dom/open-new-window "https://community.penpot.app") + :on-key-down (fn [event] + (when (kbd/enter? event) + (dom/open-new-window "https://community.penpot.app")))} + [:span.text (tr "labels.community")]] + [:li {:tab-index (if show + "0" + "-1") + :on-click #(dom/open-new-window "https://www.youtube.com/c/Penpot") + :on-key-down (fn [event] + (when (kbd/enter? event) + (dom/open-new-window "https://www.youtube.com/c/Penpot")))} + [:span.text (tr "labels.tutorials")]] + [:li {:tab-index (if show + "0" + "-1") + :on-click show-release-notes + :on-key-down (fn [event] + (when (kbd/enter? event) + (show-release-notes)))} + [:span (tr "labels.release-notes")]] - [:li.separator {:tab-index (if show - "0" - "-1") - :on-click #(on-click (du/logout) %) - :on-key-down (fn [event] - (when (kbd/enter? event) - (on-click (du/logout) event))) - :data-test "logout-profile-opt"} - [:span.icon i/exit] - [:span.text (tr "labels.logout")]]]] + [:li.separator {:tab-index (if show + "0" + "-1") + :on-click #(dom/open-new-window "https://penpot.app/libraries-templates") + :on-key-down (fn [event] + (when (kbd/enter? event) + (dom/open-new-window "https://penpot.app/libraries-templates"))) + :data-test "libraries-templates-profile-opt"} + [:span.text (tr "labels.libraries-and-templates")]] + [:li {:tab-index (if show + "0" + "-1") + :on-click #(dom/open-new-window "https://github.com/penpot/penpot") + :on-key-down (fn [event] + (when (kbd/enter? event) + (dom/open-new-window "https://github.com/penpot/penpot")))} + [:span (tr "labels.github-repo")]] + [:li {:tab-index (if show + "0" + "-1") + :on-click #(dom/open-new-window "https://penpot.app/terms") + :on-key-down (fn [event] + (when (kbd/enter? event) + (dom/open-new-window "https://penpot.app/terms")))} + [:span (tr "auth.terms-of-service")]] - (when (and team profile) - [:& comments-section {:profile profile - :team team}])])) + (when (contains? cf/flags :user-feedback) + [:li.separator {:tab-index (if show + "0" + "-1") + :on-click (partial on-click :settings-feedback) + :on-key-down (fn [event] + (when (kbd/enter? event) + (on-click :settings-feedback event))) + :data-test "feedback-profile-opt"} + [:span.text (tr "labels.give-feedback")]]) + + [:li.separator {:tab-index (if show + "0" + "-1") + :on-click #(on-click (du/logout) %) + :on-key-down (fn [event] + (when (kbd/enter? event) + (on-click (du/logout) event))) + :data-test "logout-profile-opt"} + [:span.icon i/exit] + [:span.text (tr "labels.logout")]]]] + + (when (and team profile) + [:& comments-section {:profile profile + :team team}])]))) (mf/defc sidebar {::mf/wrap-props false ::mf/wrap [mf/memo]} [props] - (let [team (obj/get props "team") + (let [new-css-system (mf/use-ctx ctx/new-css-system) + team (obj/get props "team") profile (obj/get props "profile")] - [:nav.dashboard-sidebar - [:> sidebar-content props] - [:& profile-section - {:profile profile - :team team}]])) + (if new-css-system + [:nav {:class (stl/css :dashboard-sidebar)} + [:> sidebar-content props] + [:& profile-section + {:profile profile + :team team}]] + + [:nav.dashboard-sidebar + [:> sidebar-content props] + [:& profile-section + {:profile profile + :team team}]]))) + diff --git a/frontend/src/app/main/ui/dashboard/sidebar.scss b/frontend/src/app/main/ui/dashboard/sidebar.scss new file mode 100644 index 0000000000..687d3a9689 --- /dev/null +++ b/frontend/src/app/main/ui/dashboard/sidebar.scss @@ -0,0 +1,515 @@ +@import "common/dependencies/colors"; +$fs14: 0.875rem; +$fs12: 0.75rem; +$fw400: 400; +$size-2: 0.5rem; +$size-3: 0.75rem; +$size-4: 1rem; +$br3: 3px; + +.dashboard-sidebar { + grid-row: 1 / span 2; + grid-column: 1 / span 2; + + background-color: $db-primary; + border-right: 1px solid $db-cuaternary; + margin: 0 1rem 0 0; + padding: 1rem 0 0 0; + + z-index: 1; + display: flex; + flex-direction: column; + height: 100%; +} + +.sidebar-content { + display: flex; + flex-direction: column; + height: 100%; + overflow-y: auto; + padding: 0; + + hr { + border-color: transparent; + margin: 0.8rem 15px; + } + + .back-to-dashboard { + .icon svg { + fill: $df-secondary; + } + .text { + color: $df-primary; + } + } +} + +.sidebar-team-switch { + position: relative; + display: flex; + margin: 5px 15px; + + .switch-content { + background-color: $db-tertiary; + border-radius: 8px; + height: 48px; + display: flex; + width: 100%; + border: 1px solid transparent; + align-items: center; + + svg { + fill: #8f9da3; + } + } + + .switch-icon { + display: flex; + align-items: center; + justify-content: center; + + svg { + fill: $df-secondary; + width: 10px; + height: 10px; + } + } + + .current-team { + height: 100%; + cursor: pointer; + display: flex; + align-items: center; + flex-grow: 1; + font-size: 0.875rem; + padding: 0px 10px; + background-color: transparent; + border: none; + border-right: 1px solid $db-primary; + } + + .team-name { + flex-grow: 1; + display: flex; + height: 40px; + align-items: center; + } + + .team-text { + color: $df-primary; + width: 145px; + text-overflow: ellipsis; + white-space: nowrap; + overflow: hidden; + text-align: left; + } + + .team-icon { + display: flex; + align-items: center; + padding-right: 10px; + + img { + border-radius: 50%; + flex-shrink: 0; + height: 23px; + width: 23px; + } + + svg { + width: 23px; + height: 23px; + } + } + + .switch-options { + display: flex; + max-width: 22px; + min-width: 28px; + border-left: 1px solid #e3e3e3; + justify-content: center; + align-items: center; + cursor: pointer; + background-color: transparent; + border: none; + + svg { + fill: $df-secondary; + width: 15px; + height: 13px; + } + } + + .dropdown { + right: 2px; + top: 50px; + min-width: 162px; + max-height: 30rem; + } +} + +.dropdown { + position: absolute; + z-index: 12; + background-color: $db-tertiary; + border: 1px solid $db-cuaternary; + border-radius: 8px; + box-shadow: 0px 2px 8px rgba(0, 0, 0, 0.25); + + .separator { + border-color: transparent; + margin-top: 10px; + } + + li { + border-radius: 8px; + height: 40px; + margin: 5px; + + display: flex; + align-items: center; + cursor: pointer; + font-size: 0.875rem; + padding: 5px 16px; + + .warning { + color: #e65244; + } + + &:hover { + background-color: $db-cuaternary; + } + svg { + height: 12px; + width: 12px; + } + } + + hr { + border-color: transparent; + margin: 0; + } + + &.options-dropdown { + li { + color: $df-primary; + &.warning { + color: $color-danger; + } + } + } +} + +.teams-dropdown { + background-color: $db-tertiary; + border-radius: 8px; + border: 1px solid $db-cuaternary; + min-width: 248px; + + left: 0; + top: 50px; + z-index: 12; + max-height: 30rem; + overflow-x: hidden; + overflow-y: auto; + + li { + border-radius: 8px; + height: 42px; + padding: 0 5px; + margin: 5px; + + svg { + fill: $df-secondary; + } + + &:hover { + background-color: $db-cuaternary; + .team-icon { + &.new-team { + background-color: $da-primary; + svg { + fill: $db-secondary; + } + } + } + } + .team-icon { + display: flex; + align-items: center; + } + .team-text { + color: $df-primary; + width: 165px; + } + + .new-team { + background-color: $db-cuaternary; + } + + &.action { + .team-icon { + background-color: #2e3434; + border-radius: 50%; + height: 24px; + margin-right: 10px; + padding: 6px; + width: 24px; + + svg { + height: 12px; + width: 12px; + } + } + } + } +} + +.sidebar-empty-placeholder { + padding: 10px 12px; + color: $df-secondary; + display: flex; + align-items: flex-start; + + .icon { + padding: 0px 10px; + svg { + fill: $color-gray-30; + width: 12px; + height: 12px; + } + } + .text { + font-size: $fs12; + } +} + +.sidebar-search { + align-items: center; + border: 1px solid transparent; + display: flex; + margin: 5px 15px; + + background-color: $db-tertiary; + border-radius: 8px; + margin-bottom: 2rem; + margin-top: 0; + position: relative; + + .input-text { + background: transparent; + border: 0; + font-size: 0.875rem; + margin: 0; + width: 100%; + height: 40px; + + border-radius: 8px; + color: $df-primary; + max-width: 100%; + padding: 6px 10px; + + &:focus, + &:focus-within { + border: 1px solid $da-primary; + } + } + ::placeholder { + color: $df-secondary; + } + + .search, + .clear-search { + align-items: center; + cursor: pointer; + display: flex; + height: 22px; + margin-left: auto; + padding: 0 0.5rem; + width: 32px; + + position: absolute; + top: 10px; + right: 2px; + + svg { + fill: $color-gray-30; + height: 15px; + width: 15px; + } + } + + .clear-search svg { + transform: rotate(45deg); + + &:hover { + fill: $color-danger; + } + } +} + +.sidebar-nav { + display: flex; + flex-direction: column; + overflow-y: auto; + margin: 0; + user-select: none; + + &.no-overflow { + overflow: unset; + } + + & > li { + align-items: center; + cursor: pointer; + display: flex; + flex-shrink: 0; + padding: 0.6rem 0.6rem 0.6rem 1.4rem; + a { + font-weight: $fw400; + width: 100%; + &:hover { + text-decoration: none; + } + } + + svg { + fill: $color-black; + margin-right: 8px; + height: $size-3; + width: $size-3; + } + + .element-title { + color: $df-secondary; + font-size: $fs14; + overflow: hidden; + text-overflow: ellipsis; + white-space: nowrap; + } + + &.recent-projects { + svg { + fill: $color-white; + } + } + + & .edit-wrapper { + border: 1px solid $color-gray-10; + border-radius: $br3; + display: flex; + width: 100%; + } + + input.element-title { + border: 0; + height: 30px; + padding: 5px; + margin: 0; + width: 100%; + background-color: $color-white; + } + + .close { + background-color: $color-white; + cursor: pointer; + padding-left: 5px; + + svg { + fill: $color-gray-30; + height: 15px; + transform: rotate(45deg) translateY(7px); + width: 15px; + margin: 0; + } + } + + .element-subtitle { + color: $color-gray-20; + font-style: italic; + } + + &:hover { + background-color: $db-cuaternary; + } + + &.current { + background-color: $db-cuaternary; + .element-title { + color: $da-primary; + } + } + } +} + +.profile-section { + align-items: center; + cursor: pointer; + display: flex; + padding: 10px 15px; + position: relative; + + background-color: $db-tertiary; + border-top: 1px solid $db-cuaternary; + + .profile { + align-items: center; + cursor: pointer; + display: flex; + flex-grow: 1; + + span { + // @include text-ellipsis; + color: $df-primary; + margin: 10px; + font-size: $fs14; + max-width: 160px; + } + + img { + border-radius: 50%; + flex-shrink: 0; + height: 25px; + width: 25px; + } + svg { + height: 10px; + margin-left: auto; + margin-right: $size-2; + width: 10px; + } + } + + .dropdown { + left: 15px; + bottom: 45px; + + background-color: #212426; + border: 1px solid #2e3434; + border-radius: 8px; + min-width: 252px; + + // @include animation(0, 0.2s, fadeInUp); + + li { + font-size: $fs14; + padding: $size-2 $size-4; + + svg { + fill: $color-gray-20; + margin-right: $size-2; + + height: 12px; + width: 12px; + } + + .text { + color: #ffffff; + } + + &.separator { + border-top: 1px solid transparent; + } + } + } +} diff --git a/frontend/src/app/main/ui/dashboard/team.cljs b/frontend/src/app/main/ui/dashboard/team.cljs index 9e854ce2b4..dcb5cf8c2c 100644 --- a/frontend/src/app/main/ui/dashboard/team.cljs +++ b/frontend/src/app/main/ui/dashboard/team.cljs @@ -36,7 +36,8 @@ {::mf/wrap [mf/memo] ::mf/wrap-props false} [{:keys [section team]}] - (let [on-nav-members (mf/use-fn #(st/emit! (dd/go-to-team-members))) + (let [new-css-system (mf/use-ctx ctx/new-css-system) + on-nav-members (mf/use-fn #(st/emit! (dd/go-to-team-members))) on-nav-settings (mf/use-fn #(st/emit! (dd/go-to-team-settings))) on-nav-invitations (mf/use-fn #(st/emit! (dd/go-to-team-invitations))) on-nav-webhooks (mf/use-fn #(st/emit! (dd/go-to-team-webhooks))) @@ -55,32 +56,62 @@ :team team :origin :team}))))] - [:header.dashboard-header.team - [:div.dashboard-title - [:h1 (cond - members-section? (tr "labels.members") - settings-section? (tr "labels.settings") - invitations-section? (tr "labels.invitations") - webhooks-section? (tr "labels.webhooks") - :else nil)]] - [:nav.dashboard-header-menu - [:ul.dashboard-header-options - [:li {:class (when members-section? "active")} - [:a {:on-click on-nav-members} (tr "labels.members")]] - [:li {:class (when invitations-section? "active")} - [:a {:on-click on-nav-invitations} (tr "labels.invitations")]] - (when (contains? cfg/flags :webhooks) - [:li {:class (when webhooks-section? "active")} - [:a {:on-click on-nav-webhooks} (tr "labels.webhooks")]]) - [:li {:class (when settings-section? "active")} - [:a {:on-click on-nav-settings} (tr "labels.settings")]]]] - [:div.dashboard-buttons - (if (and (or invitations-section? members-section?) (:is-admin permissions)) - [:a.btn-secondary.btn-small - {:on-click on-invite-member - :data-test "invite-member"} - (tr "dashboard.invite-profile")] - [:div.blank-space])]])) + (if new-css-system + [:header {:class (stl/css :dashboard-header :team)} + [:div {:class (stl/css :dashboard-title)} + [:h1 (cond + members-section? (tr "labels.members") + settings-section? (tr "labels.settings") + invitations-section? (tr "labels.invitations") + webhooks-section? (tr "labels.webhooks") + :else nil)]] + [:nav {:class (stl/css :dashboard-header-menu)} + [:ul {:class (stl/css :dashboard-header-options)} + [:li {:class (when members-section? (stl/css :active))} + [:a {:on-click on-nav-members} (tr "labels.members")]] + [:li {:class (when invitations-section? (stl/css :active))} + [:a {:on-click on-nav-invitations} (tr "labels.invitations")]] + (when (contains? cfg/flags :webhooks) + [:li {:class (when webhooks-section? (stl/css :active))} + [:a {:on-click on-nav-webhooks} (tr "labels.webhooks")]]) + [:li {:class (when settings-section? (stl/css :active))} + [:a {:on-click on-nav-settings} (tr "labels.settings")]]]] + [:div {:class (stl/css :dashboard-buttons)} + (if (and (or invitations-section? members-section?) (:is-admin permissions)) + [:a + {:class (stl/css :btn-secondary :btn-small) + :on-click on-invite-member + :data-test "invite-member"} + (tr "dashboard.invite-profile")] + [:div {:class (stl/css :blank-space)}])]] + + ;; OLD + [:header.dashboard-header.team + [:div.dashboard-title + [:h1 (cond + members-section? (tr "labels.members") + settings-section? (tr "labels.settings") + invitations-section? (tr "labels.invitations") + webhooks-section? (tr "labels.webhooks") + :else nil)]] + [:nav.dashboard-header-menu + [:ul.dashboard-header-options + [:li {:class (when members-section? "active")} + [:a {:on-click on-nav-members} (tr "labels.members")]] + [:li {:class (when invitations-section? "active")} + [:a {:on-click on-nav-invitations} (tr "labels.invitations")]] + (when (contains? cfg/flags :webhooks) + [:li {:class (when webhooks-section? "active")} + [:a {:on-click on-nav-webhooks} (tr "labels.webhooks")]]) + [:li {:class (when settings-section? "active")} + [:a {:on-click on-nav-settings} (tr "labels.settings")]]]] + [:div.dashboard-buttons + (if (and (or invitations-section? members-section?) (:is-admin permissions)) + [:a.btn-secondary.btn-small + {:on-click on-invite-member + :data-test "invite-member"} + (tr "dashboard.invite-profile")] + [:div.blank-space])]]))) ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; INVITATIONS MODAL @@ -239,20 +270,33 @@ (mf/defc member-info {::mf/wrap-props false} [{:keys [member profile]}] - (let [is-you? (= (:id profile) (:id member))] - [:* - [:div.member-image - [:img {:src (cfg/resolve-profile-photo-url member)}]] - [:div.member-info - [:div.member-name (:name member) - (when is-you? - [:span.you (tr "labels.you")])] - [:div.member-email (:email member)]]])) + (let [new-css-system (mf/use-ctx ctx/new-css-system) + is-you? (= (:id profile) (:id member))] + (if new-css-system + [:* + [:div {:class (stl/css :member-image)} + [:img {:src (cfg/resolve-profile-photo-url member)}]] + [:div {:class (stl/css :member-info)} + [:div {:class (stl/css :member-name)} (:name member) + (when is-you? + [:span {:class (stl/css :you)} (tr "labels.you")])] + [:div {:class (stl/css :member-email)} (:email member)]]] + + ;; OLD + [:* + [:div.member-image + [:img {:src (cfg/resolve-profile-photo-url member)}]] + [:div.member-info + [:div.member-name (:name member) + (when is-you? + [:span.you (tr "labels.you")])] + [:div.member-email (:email member)]]]))) (mf/defc rol-info {::mf/wrap-props false} [{:keys [member team on-set-admin on-set-editor on-set-owner profile]}] - (let [member-is-owner? (:is-owner member) + (let [new-css-system (mf/use-ctx ctx/new-css-system) + member-is-owner? (:is-owner member) member-is-admin? (and (:is-admin member) (not member-is-owner?)) member-is-editor? (and (:can-edit member) (and (not member-is-admin?) (not member-is-owner?))) show? (mf/use-state false) @@ -272,28 +316,50 @@ on-show (mf/use-fn #(reset! show? true)) on-hide (mf/use-fn #(reset! show? false))] - [:* - (if (and can-change-rol? not-superior? (not (and is-you? you-owner?))) - [:div.rol-selector.has-priv {:on-click on-show} - [:span.rol-label (tr role)] - [:span.icon i/arrow-down]] - [:div.rol-selector - [:span.rol-label (tr role)]]) + (if new-css-system + [:* + (if (and can-change-rol? not-superior? (not (and is-you? you-owner?))) + [:div {:class (stl/css :rol-selector :has-priv) + :on-click on-show} + [:span {:class (stl/css :rol-label)} (tr role)] + [:span {:class (stl/css :icon)} i/arrow-down]] + [:div {:class (stl/css :rol-selector)} + [:span {:class (stl/css :rol-label)} (tr role)]]) - [:& dropdown {:show @show? :on-close on-hide} - [:ul.dropdown.options-dropdown - [:li {:on-click on-set-admin} (tr "labels.admin")] - [:li {:on-click on-set-editor} (tr "labels.editor")] - ;; Temporarily disabled viewer role - ;; https://tree.taiga.io/project/penpot/issue/1083 - ;; [:li {:on-click set-viewer} (tr "labels.viewer")] - (when you-owner? - [:li {:on-click (partial on-set-owner member)} (tr "labels.owner")])]]])) + [:& dropdown {:show @show? :on-close on-hide} + [:ul {:class (stl/css :dropdown :options-dropdown)} + [:li {:on-click on-set-admin} (tr "labels.admin")] + [:li {:on-click on-set-editor} (tr "labels.editor")] + ;; Temporarily disabled viewer role + ;; https://tree.taiga.io/project/penpot/issue/1083 + ;; [:li {:on-click set-viewer} (tr "labels.viewer")] + (when you-owner? + [:li {:on-click (partial on-set-owner member)} (tr "labels.owner")])]]] + + ;; OLD + [:* + (if (and can-change-rol? not-superior? (not (and is-you? you-owner?))) + [:div.rol-selector.has-priv {:on-click on-show} + [:span.rol-label (tr role)] + [:span.icon i/arrow-down]] + [:div.rol-selector + [:span.rol-label (tr role)]]) + + [:& dropdown {:show @show? :on-close on-hide} + [:ul.dropdown.options-dropdown + [:li {:on-click on-set-admin} (tr "labels.admin")] + [:li {:on-click on-set-editor} (tr "labels.editor")] + ;; Temporarily disabled viewer role + ;; https://tree.taiga.io/project/penpot/issue/1083 + ;; [:li {:on-click set-viewer} (tr "labels.viewer")] + (when you-owner? + [:li {:on-click (partial on-set-owner member)} (tr "labels.owner")])]]]))) (mf/defc member-actions {::mf/wrap-props false} [{:keys [member team on-delete on-leave profile]}] - (let [is-owner? (:is-owner member) + (let [new-css-system (mf/use-ctx ctx/new-css-system) + is-owner? (:is-owner member) owner? (dm/get-in team [:permissions :is-owner]) admin? (dm/get-in team [:permissions :is-admin]) show? (mf/use-state false) @@ -303,16 +369,30 @@ on-show (mf/use-fn #(reset! show? true)) on-hide (mf/use-fn #(reset! show? false))] - [:* - (when (or is-you? (and can-delete? (not (and is-owner? (not owner?))))) - [:span.icon {:on-click on-show} [i/actions]]) + (if new-css-system + [:* + (when (or is-you? (and can-delete? (not (and is-owner? (not owner?))))) + [:span {:class (stl/css :icon) + :on-click on-show} [i/actions]]) - [:& dropdown {:show @show? :on-close on-hide} - [:ul.dropdown.actions-dropdown - (when is-you? - [:li {:on-click on-leave} (tr "dashboard.leave-team")]) - (when (and can-delete? (not is-you?) (not (and is-owner? (not owner?)))) - [:li {:on-click on-delete} (tr "labels.remove-member")])]]])) + [:& dropdown {:show @show? :on-close on-hide} + [:ul {:class (stl/css :dropdown :actions-dropdown)} + (when is-you? + [:li {:on-click on-leave} (tr "dashboard.leave-team")]) + (when (and can-delete? (not is-you?) (not (and is-owner? (not owner?)))) + [:li {:on-click on-delete} (tr "labels.remove-member")])]]] + + ;; OLD + [:* + (when (or is-you? (and can-delete? (not (and is-owner? (not owner?))))) + [:span.icon {:on-click on-show} [i/actions]]) + + [:& dropdown {:show @show? :on-close on-hide} + [:ul.dropdown.actions-dropdown + (when is-you? + [:li {:on-click on-leave} (tr "dashboard.leave-team")]) + (when (and can-delete? (not is-you?) (not (and is-owner? (not owner?)))) + [:li {:on-click on-delete} (tr "labels.remove-member")])]]]))) (defn- set-role! [member-id role] (let [params {:member-id member-id :role role}] @@ -323,7 +403,8 @@ ::mf/wrap-props false} [{:keys [team member members profile]}] - (let [member-id (:id member) + (let [new-css-system (mf/use-ctx ctx/new-css-system) + member-id (:id member) on-set-admin (mf/use-fn (mf/deps member-id) (partial set-role! member-id :admin)) on-set-editor (mf/use-fn (mf/deps member-id) (partial set-role! member-id :editor)) owner? (dm/get-in team [:permissions :is-owner]) @@ -432,29 +513,50 @@ (= true owner?) on-change-owner-and-leave :else on-leave)] - [:div.table-row - [:div.table-field.name - [:& member-info {:member member :profile profile}]] + (if new-css-system + [:div {:class (stl/css :table-row)} + [:div {:class (stl/css :table-field :name)} + [:& member-info {:member member :profile profile}]] - [:div.table-field.roles - [:& rol-info {:member member - :team team - :on-set-admin on-set-admin - :on-set-editor on-set-editor - :on-set-owner on-set-owner - :profile profile}]] + [:div {:class (stl/css :table-field :roles)} + [:& rol-info {:member member + :team team + :on-set-admin on-set-admin + :on-set-editor on-set-editor + :on-set-owner on-set-owner + :profile profile}]] - [:div.table-field.actions - [:& member-actions {:member member - :profile profile - :team team - :on-delete on-delete - :on-leave on-leave'}]]])) + [:div {:class (stl/css :table-field :actions)} + [:& member-actions {:member member + :profile profile + :team team + :on-delete on-delete + :on-leave on-leave'}]]] + ;; OLD + [:div.table-row + [:div.table-field.name + [:& member-info {:member member :profile profile}]] + + [:div.table-field.roles + [:& rol-info {:member member + :team team + :on-set-admin on-set-admin + :on-set-editor on-set-editor + :on-set-owner on-set-owner + :profile profile}]] + + [:div.table-field.actions + [:& member-actions {:member member + :profile profile + :team team + :on-delete on-delete + :on-leave on-leave'}]]]))) (mf/defc team-members {::mf/wrap-props false} [{:keys [members-map team profile]}] - (let [members (mf/with-memo [members-map] + (let [new-css-system (mf/use-ctx ctx/new-css-system) + members (mf/with-memo [members-map] (->> (vals members-map) (sort-by :created-at) (remove :is-owner))) @@ -462,30 +564,53 @@ (->> (vals members-map) (d/seek :is-owner)))] - [:div.dashboard-table.team-members - [:div.table-header - [:div.table-field.name (tr "labels.member")] - [:div.table-field.role (tr "labels.role")]] + (if new-css-system + [:div {:class (stl/css :dashboard-table :team-members)} + [:div {:class (stl/css :table-header)} + [:div {:class (stl/css :table-field :name)} (tr "labels.member")] + [:div {:class (stl/css :table-field :role)} (tr "labels.role")]] - [:div.table-rows - [:& team-member - {:member owner - :team team - :profile profile - :members members-map}] - - (for [item members] + [:div {:class (stl/css :table-rows)} [:& team-member - {:member item + {:member owner :team team :profile profile - :key (:id item) - :members members-map}])]])) + :members members-map}] + + (for [item members] + [:& team-member + {:member item + :team team + :profile profile + :key (:id item) + :members members-map}])]] + + ;; OLD + [:div.dashboard-table.team-members + [:div.table-header + [:div.table-field.name (tr "labels.member")] + [:div.table-field.role (tr "labels.role")]] + + [:div.table-rows + [:& team-member + {:member owner + :team team + :profile profile + :members members-map}] + + (for [item members] + [:& team-member + {:member item + :team team + :profile profile + :key (:id item) + :members members-map}])]]))) (mf/defc team-members-page {::mf/wrap-props false} [{:keys [team profile]}] - (let [members-map (mf/deref refs/dashboard-team-members)] + (let [new-css-system (mf/use-ctx ctx/new-css-system) + members-map (mf/deref refs/dashboard-team-members)] (mf/with-effect [team] (dom/set-html-title @@ -497,13 +622,23 @@ (mf/with-effect [team] (st/emit! (dd/fetch-team-members (:id team)))) - [:* - [:& header {:section :dashboard-team-members :team team}] - [:section.dashboard-container.dashboard-team-members - [:& team-members - {:profile profile - :team team - :members-map members-map}]]])) + (if new-css-system + [:* + [:& header {:section :dashboard-team-members :team team}] + [:section {:class (stl/css :dashboard-container :dashboard-team-members)} + [:& team-members + {:profile profile + :team team + :members-map members-map}]]] + + ;; OLD + [:* + [:& header {:section :dashboard-team-members :team team}] + [:section.dashboard-container.dashboard-team-members + [:& team-members + {:profile profile + :team team + :members-map members-map}]]]))) ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; INVITATIONS SECTION @@ -512,7 +647,8 @@ (mf/defc invitation-role-selector {::mf/wrap-props false} [{:keys [can-invite? role status on-change]}] - (let [show? (mf/use-state false) + (let [new-css-system (mf/use-ctx ctx/new-css-system) + show? (mf/use-state false) label (cond (= role :owner) (tr "labels.owner") (= role :admin) (tr "labels.admin") @@ -531,35 +667,65 @@ (keyword))] (on-change role event))))] - [:* - (if (and can-invite? (= status :pending)) - [:div.rol-selector.has-priv {:on-click on-show} - [:span.rol-label label] - [:span.icon i/arrow-down]] - [:div.rol-selector - [:span.rol-label label]]) + (if new-css-system + [:* + (if (and can-invite? (= status :pending)) + [:div {:class (stl/css :rol-selector :has-priv) + :on-click on-show} + [:span {:class (stl/css :rol-label)} label] + [:span {:class (stl/css :icon)} i/arrow-down]] + [:div {:class (stl/css :rol-selector)} + [:span {:class (stl/css :rol-label)} label]]) - [:& dropdown {:show @show? :on-close on-hide} - [:ul.dropdown.options-dropdown - [:li {:data-role "admin" :on-click on-change'} (tr "labels.admin")] - [:li {:data-role "editor" :on-click on-change'} (tr "labels.editor")]]]])) + [:& dropdown {:show @show? :on-close on-hide} + [:ul.dropdown.options-dropdown + [:li {:data-role "admin" :on-click on-change'} (tr "labels.admin")] + [:li {:data-role "editor" :on-click on-change'} (tr "labels.editor")]]]] + + ;; OLD + [:* + (if (and can-invite? (= status :pending)) + [:div.rol-selector.has-priv {:on-click on-show} + [:span.rol-label label] + [:span.icon i/arrow-down]] + [:div.rol-selector + [:span.rol-label label]]) + + [:& dropdown {:show @show? :on-close on-hide} + [:ul.dropdown.options-dropdown + [:li {:data-role "admin" :on-click on-change'} (tr "labels.admin")] + [:li {:data-role "editor" :on-click on-change'} (tr "labels.editor")]]]]))) (mf/defc invitation-status-badge {::mf/wrap-props false} [{:keys [status]}] - [:div.status-badge - {:class (dom/classnames - :expired (= status :expired) - :pending (= status :pending))} - [:span.status-label - (if (= status :expired) - (tr "labels.expired-invitation") - (tr "labels.pending-invitation"))]]) + (let [new-css-system (mf/use-ctx ctx/new-css-system)] + (if new-css-system + [:div + {:class (stl/css-case + :status-badge true + :expired (= status :expired) + :pending (= status :pending))} + [:span {:class (stl/css :status-label)} + (if (= status :expired) + (tr "labels.expired-invitation") + (tr "labels.pending-invitation"))]] + + ;; OLD + [:div.status-badge + {:class (dom/classnames + :expired (= status :expired) + :pending (= status :pending))} + [:span.status-label + (if (= status :expired) + (tr "labels.expired-invitation") + (tr "labels.pending-invitation"))]]))) (mf/defc invitation-actions {::mf/wrap-props false} [{:keys [invitation team-id]}] - (let [show? (mf/use-state false) + (let [new-css-system (mf/use-ctx ctx/new-css-system) + show? (mf/use-state false) email (:email invitation) role (:role invitation) @@ -634,20 +800,32 @@ on-hide (mf/use-fn #(reset! show? false)) on-show (mf/use-fn #(reset! show? true))] - [:* - [:span.icon {:on-click on-show} [i/actions]] - [:& dropdown {:show @show? :on-close on-hide} - [:ul.dropdown.actions-dropdown - [:li {:on-click on-copy} (tr "labels.copy-invitation-link")] - [:li {:on-click on-resend} (tr "labels.resend-invitation")] - [:li {:on-click on-delete} (tr "labels.delete-invitation")]]]])) + (if new-css-system + [:* + [:span {:class (stl/css :icon) + :on-click on-show} [i/actions]] + [:& dropdown {:show @show? :on-close on-hide} + [:ul {:class (stl/css :dropdown :actions-dropdown)} + [:li {:on-click on-copy} (tr "labels.copy-invitation-link")] + [:li {:on-click on-resend} (tr "labels.resend-invitation")] + [:li {:on-click on-delete} (tr "labels.delete-invitation")]]]] + + ;; OLD + [:* + [:span.icon {:on-click on-show} [i/actions]] + [:& dropdown {:show @show? :on-close on-hide} + [:ul.dropdown.actions-dropdown + [:li {:on-click on-copy} (tr "labels.copy-invitation-link")] + [:li {:on-click on-resend} (tr "labels.resend-invitation")] + [:li {:on-click on-delete} (tr "labels.delete-invitation")]]]]))) (mf/defc invitation-row {::mf/wrap [mf/memo] ::mf/wrap-props false} [{:keys [invitation can-invite? team-id] :as props}] - (let [expired? (:expired invitation) + (let [new-css-system (mf/use-ctx ctx/new-css-system) + expired? (:expired invitation) email (:email invitation) role (:role invitation) status (if expired? :expired :pending) @@ -660,58 +838,106 @@ mdata {:on-success #(st/emit! (dd/fetch-team-invitations))}] (st/emit! (dd/update-team-invitation-role (with-meta params mdata))))))] - [:div.table-row - [:div.table-field.mail email] + (if new-css-system + [:div {:class (stl/css :table-row)} + [:div {:class (stl/css :table-field :mail)} email] - [:div.table-field.roles - [:& invitation-role-selector - {:can-invite? can-invite? - :role role - :status status - :on-change on-change-role}]] + [:div {:class (stl/css :table-field :roles)} + [:& invitation-role-selector + {:can-invite? can-invite? + :role role + :status status + :on-change on-change-role}]] - [:div.table-field.status - [:& invitation-status-badge {:status status}]] + [:div {:class (stl/css :table-field :status)} + [:& invitation-status-badge {:status status}]] - [:div.table-field.actions - (when can-invite? - [:& invitation-actions - {:invitation invitation - :team-id team-id}])]])) + [:div {:class (stl/css :table-field :actions)} + (when can-invite? + [:& invitation-actions + {:invitation invitation + :team-id team-id}])]] + + ;; OLD + [:div.table-row + [:div.table-field.mail email] + + [:div.table-field.roles + [:& invitation-role-selector + {:can-invite? can-invite? + :role role + :status status + :on-change on-change-role}]] + + [:div.table-field.status + [:& invitation-status-badge {:status status}]] + + [:div.table-field.actions + (when can-invite? + [:& invitation-actions + {:invitation invitation + :team-id team-id}])]]))) (mf/defc empty-invitation-table [{:keys [can-invite?] :as props}] - [:div.empty-invitations - [:span (tr "labels.no-invitations")] - (when can-invite? - [:& i18n/tr-html {:label "labels.no-invitations-hint" - :tag-name "span"}])]) + (let [new-css-system (mf/use-ctx ctx/new-css-system)] + (if new-css-system + [:div {:class (stl/css :empty-invitations)} + [:span (tr "labels.no-invitations")] + (when can-invite? + [:& i18n/tr-html {:label "labels.no-invitations-hint" + :tag-name "span"}])] + ;; OLD + [:div.empty-invitations + [:span (tr "labels.no-invitations")] + (when can-invite? + [:& i18n/tr-html {:label "labels.no-invitations-hint" + :tag-name "span"}])]))) (mf/defc invitation-section [{:keys [team invitations] :as props}] - (let [owner? (dm/get-in team [:permissions :is-owner]) + (let [new-css-system (mf/use-ctx ctx/new-css-system) + owner? (dm/get-in team [:permissions :is-owner]) admin? (dm/get-in team [:permissions :is-admin]) can-invite? (or owner? admin?) team-id (:id team)] - [:div.dashboard-table.invitations - [:div.table-header - [:div.table-field.name (tr "labels.invitations")] - [:div.table-field.role (tr "labels.role")] - [:div.table-field.status (tr "labels.status")]] - (if (empty? invitations) - [:& empty-invitation-table {:can-invite? can-invite?}] - [:div.table-rows - (for [invitation invitations] - [:& invitation-row - {:key (:email invitation) - :invitation invitation - :can-invite? can-invite? - :team-id team-id}])])])) + (if new-css-system + [:div {:class (stl/css :dashboard-table :invitations)} + [:div {:class (stl/css :table-header)} + [:div {:class (stl/css :table-field :name)} (tr "labels.invitations")] + [:div {:class (stl/css :table-field :role)} (tr "labels.role")] + [:div {:class (stl/css :table-field :status)} (tr "labels.status")]] + (if (empty? invitations) + [:& empty-invitation-table {:can-invite? can-invite?}] + [:div {:class (stl/css :table-rows)} + (for [invitation invitations] + [:& invitation-row + {:key (:email invitation) + :invitation invitation + :can-invite? can-invite? + :team-id team-id}])])] + + ;; OLD + [:div.dashboard-table.invitations + [:div.table-header + [:div.table-field.name (tr "labels.invitations")] + [:div.table-field.role (tr "labels.role")] + [:div.table-field.status (tr "labels.status")]] + (if (empty? invitations) + [:& empty-invitation-table {:can-invite? can-invite?}] + [:div.table-rows + (for [invitation invitations] + [:& invitation-row + {:key (:email invitation) + :invitation invitation + :can-invite? can-invite? + :team-id team-id}])])]))) (mf/defc team-invitations-page [{:keys [team] :as props}] - (let [invitations (mf/deref refs/dashboard-team-invitations)] + (let [new-css-system (mf/use-ctx ctx/new-css-system) + invitations (mf/deref refs/dashboard-team-invitations)] (mf/with-effect [team] (dom/set-html-title @@ -723,12 +949,21 @@ (mf/with-effect [] (st/emit! (dd/fetch-team-invitations))) - [:* - [:& header {:section :dashboard-team-invitations - :team team}] - [:section.dashboard-container.dashboard-team-invitations - [:& invitation-section {:team team - :invitations invitations}]]])) + (if new-css-system + [:* + [:& header {:section :dashboard-team-invitations + :team team}] + [:section {:class (stl/css :dashboard-container :dashboard-team-invitations)} + [:& invitation-section {:team team + :invitations invitations}]]] + + ;; OLD + [:* + [:& header {:section :dashboard-team-invitations + :team team}] + [:section.dashboard-container.dashboard-team-invitations + [:& invitation-section {:team team + :invitations invitations}]]]))) ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; WEBHOOKS SECTION @@ -861,7 +1096,7 @@ (tr "modals.edit-webhook.submit-label") (tr "modals.create-webhook.submit-label"))}]]]]]] - + ;; OLD [:div.modal-overlay [:div.modal-container.webhooks-modal [:& fm/form {:form form :on-submit on-submit} @@ -913,51 +1148,91 @@ (mf/defc webhooks-hero {::mf/wrap-props false} [] - [:div.banner + #_[:div.banner [:div.title (tr "labels.webhooks") [:div.description (tr "dashboard.webhooks.description")]] [:div.create-container [:div.create (tr "dashboard.webhooks.create")]]] - [:div.webhooks-hero-container - [:div.webhooks-hero - [:div.desc - [:h2 (tr "labels.webhooks")] - [:& i18n/tr-html {:label "dashboard.webhooks.description"}]] + (let [new-css-system (mf/use-ctx ctx/new-css-system)] + (if new-css-system + [:div {:class (stl/css :webhooks-hero-container)} + [:div {:class (stl/css :webhooks-hero)} + [:div {:class (stl/css :desc)} + [:h2 (tr "labels.webhooks")] + [:& i18n/tr-html {:label "dashboard.webhooks.description"}]] - [:div.btn-primary - {:on-click #(st/emit! (modal/show :webhook {}))} - [:span (tr "dashboard.webhooks.create")]]]]) + [:div + {:class (stl/css :btn-primary) + :on-click #(st/emit! (modal/show :webhook {}))} + [:span (tr "dashboard.webhooks.create")]]]] + + ;; OLD + [:div.webhooks-hero-container + [:div.webhooks-hero + [:div.desc + [:h2 (tr "labels.webhooks")] + [:& i18n/tr-html {:label "dashboard.webhooks.description"}]] + + [:div.btn-primary + {:on-click #(st/emit! (modal/show :webhook {}))} + [:span (tr "dashboard.webhooks.create")]]]]))) (mf/defc webhook-actions {::mf/wrap-props false} [{:keys [on-edit on-delete]}] - (let [show? (mf/use-state false) + (let [new-css-system (mf/use-ctx ctx/new-css-system) + + show? (mf/use-state false) on-show (mf/use-fn #(reset! show? true)) on-hide (mf/use-fn #(reset! show? false))] - [:* - [:span.icon {:on-click on-show} [i/actions]] - [:& dropdown {:show @show? :on-close on-hide} - [:ul.dropdown.actions-dropdown - [:li {:on-click on-edit} (tr "labels.edit")] - [:li {:on-click on-delete} (tr "labels.delete")]]]])) + + (if new-css-system + [:* + [:span {:class (stl/css :icon) + :on-click on-show} [i/actions]] + [:& dropdown {:show @show? :on-close on-hide} + [:ul {:class (stl/css :dropdown :actions-dropdown)} + [:li {:on-click on-edit} (tr "labels.edit")] + [:li {:on-click on-delete} (tr "labels.delete")]]]] + + ;; OLD + [:* + [:span.icon {:on-click on-show} [i/actions]] + [:& dropdown {:show @show? :on-close on-hide} + [:ul.dropdown.actions-dropdown + [:li {:on-click on-edit} (tr "labels.edit")] + [:li {:on-click on-delete} (tr "labels.delete")]]]]))) (mf/defc last-delivery-icon {::mf/wrap-props false} [{:keys [success? text]}] - [:div.last-delivery-icon - [:div.tooltip - [:div.label text] - [:div.arrow-down]] - (if success? - [:span.icon.success i/msg-success] - [:span.icon.failure i/msg-warning])]) + (let [new-css-system (mf/use-ctx ctx/new-css-system)] + (if new-css-system + [:div {:class (stl/css :last-delivery-icon)} + [:div {:class (stl/css :tooltip)} + [:div {:class (stl/css :label)} text] + [:div {:class (stl/css :arrow-down)}]] + (if success? + [:span {:class (stl/css :icon :success)} i/msg-success] + [:span {:class (stl/css :icon :failure)} i/msg-warning])] + + ;; OLD + [:div.last-delivery-icon + [:div.tooltip + [:div.label text] + [:div.arrow-down]] + (if success? + [:span.icon.success i/msg-success] + [:span.icon.failure i/msg-warning])]))) (mf/defc webhook-item {::mf/wrap [mf/memo]} [{:keys [webhook] :as props}] - (let [error-code (:error-code webhook) + (let [new-css-system (mf/use-ctx ctx/new-css-system) + + error-code (:error-code webhook) id (:id webhook) on-edit @@ -996,35 +1271,64 @@ (str/starts-with? error-code "unexpected-status") (dm/str " " (tr "errors.webhooks.unexpected-status" (extract-status error-code))))))] - [:div.table-row - [:div.table-field.last-delivery - [:div.icon-container - [:& last-delivery-icon - {:success? (nil? error-code) - :text last-delivery-text}]]] - [:div.table-field.uri - [:div (dm/str (:uri webhook))]] - [:div.table-field.active - [:div (if (:is-active webhook) - (tr "labels.active") - (tr "labels.inactive"))]] - [:div.table-field.actions - [:& webhook-actions - {:on-edit on-edit - :on-delete on-delete}]]])) + + (if new-css-system + [:div {:class (stl/css :table-row)} + [:div {:class (stl/css :table-field :last-delivery)} + [:div {:class (stl/css :icon-container)} + [:& last-delivery-icon + {:success? (nil? error-code) + :text last-delivery-text}]]] + [:div {:class (stl/css :table-field :uri)} + [:div (dm/str (:uri webhook))]] + [:div {:class (stl/css :table-field :active)} + [:div (if (:is-active webhook) + (tr "labels.active") + (tr "labels.inactive"))]] + [:div {:class (stl/css :table-field :actions)} + [:& webhook-actions + {:on-edit on-edit + :on-delete on-delete}]]] + + ;; OLD + [:div.table-row + [:div.table-field.last-delivery + [:div.icon-container + [:& last-delivery-icon + {:success? (nil? error-code) + :text last-delivery-text}]]] + [:div.table-field.uri + [:div (dm/str (:uri webhook))]] + [:div.table-field.active + [:div (if (:is-active webhook) + (tr "labels.active") + (tr "labels.inactive"))]] + [:div.table-field.actions + [:& webhook-actions + {:on-edit on-edit + :on-delete on-delete}]]]))) (mf/defc webhooks-list {::mf/wrap-props false} [{:keys [webhooks]}] - [:div.dashboard-table - [:div.table-rows - (for [webhook webhooks] - [:& webhook-item {:webhook webhook :key (:id webhook)}])]]) + (let [new-css-system (mf/use-ctx ctx/new-css-system)] + (if new-css-system + [:div {:class (stl/css :dashboard-table)} + [:div {:class (stl/css :table-rows)} + (for [webhook webhooks] + [:& webhook-item {:webhook webhook :key (:id webhook)}])]] + + ;; OLD + [:div.dashboard-table + [:div.table-rows + (for [webhook webhooks] + [:& webhook-item {:webhook webhook :key (:id webhook)}])]]))) (mf/defc team-webhooks-page {::mf/wrap-props false} [{:keys [team]}] - (let [webhooks (mf/deref refs/dashboard-team-webhooks)] + (let [new-css-system (mf/use-ctx ctx/new-css-system) + webhooks (mf/deref refs/dashboard-team-webhooks)] (mf/with-effect [team] (dom/set-html-title @@ -1036,16 +1340,29 @@ (mf/with-effect [team] (st/emit! (dd/fetch-team-webhooks))) - [:* - [:& header {:team team :section :dashboard-team-webhooks}] - [:section.dashboard-container.dashboard-team-webhooks + (if new-css-system [:* - [:& webhooks-hero] - (if (empty? webhooks) - [:div.webhooks-empty - [:div (tr "dashboard.webhooks.empty.no-webhooks")] - [:div (tr "dashboard.webhooks.empty.add-one")]] - [:& webhooks-list {:webhooks webhooks}])]]])) + [:& header {:team team :section :dashboard-team-webhooks}] + [:section {:class (stl/css :dashboard-container :dashboard-team-webhooks)} + [:* + [:& webhooks-hero] + (if (empty? webhooks) + [:div {:class (stl/css :webhooks-empty)} + [:div (tr "dashboard.webhooks.empty.no-webhooks")] + [:div (tr "dashboard.webhooks.empty.add-one")]] + [:& webhooks-list {:webhooks webhooks}])]]] + + ;; OLD + [:* + [:& header {:team team :section :dashboard-team-webhooks}] + [:section.dashboard-container.dashboard-team-webhooks + [:* + [:& webhooks-hero] + (if (empty? webhooks) + [:div.webhooks-empty + [:div (tr "dashboard.webhooks.empty.no-webhooks")] + [:div (tr "dashboard.webhooks.empty.add-one")]] + [:& webhooks-list {:webhooks webhooks}])]]]))) ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; SETTINGS SECTION @@ -1054,7 +1371,8 @@ (mf/defc team-settings-page {::mf/wrap-props false} [{:keys [team]}] - (let [finput (mf/use-ref) + (let [new-css-system (mf/use-ctx ctx/new-css-system) + finput (mf/use-ref) members-map (mf/deref refs/dashboard-team-members) owner (->> (vals members-map) @@ -1086,38 +1404,78 @@ (st/emit! (dd/fetch-team-members team-id) (dd/fetch-team-stats team-id)))) - [:* - [:& header {:section :dashboard-team-settings :team team}] - [:section.dashboard-container.dashboard-team-settings - [:div.team-settings - [:div.horizontal-blocks - [:div.block.info-block - [:div.label (tr "dashboard.team-info")] - [:div.name (:name team)] - [:div.icon - (when can-edit? - [:span.update-overlay {:on-click on-image-click} i/image]) - [:img {:src (cfg/resolve-team-photo-url team)}] - (when can-edit? - [:& file-uploader {:accept "image/jpeg,image/png" - :multi false - :ref finput - :on-selected on-file-selected}])]] + (if new-css-system + [:* + [:& header {:section :dashboard-team-settings :team team}] + [:section {:class (stl/css :dashboard-container :dashboard-team-settings)} + [:div {:class (stl/css :team-settings)} + [:div {:class (stl/css :horizontal-blocks)} + [:div {:class (stl/css :block :info-block)} + [:div {:class (stl/css :label)} (tr "dashboard.team-info")] + [:div {:class (stl/css :name)} (:name team)] + [:div {:class (stl/css :icon)} + (when can-edit? + [:span {:class (stl/css :update-overlay) + :on-click on-image-click} i/image]) + [:img {:src (cfg/resolve-team-photo-url team)}] + (when can-edit? + [:& file-uploader {:accept "image/jpeg,image/png" + :multi false + :ref finput + :on-selected on-file-selected}])]] + + [:div {:class (stl/css :block :owner-block)} + [:div {:class (stl/css :label)} (tr "dashboard.team-members")] + [:div {:class (stl/css :owner)} + [:span {:class (stl/css :icon)} [:img {:src (cfg/resolve-profile-photo-url owner)}]] + [:span {:class (stl/css :text)} (str (:name owner) " (" (tr "labels.owner") ")")]] + [:div {:class (stl/css :summary)} + [:span {:class (stl/css :icon)} i/user] + [:span {:class (stl/css :text)} (tr "dashboard.num-of-members" (count members-map))]]] + + [:div {:class (stl/css :block :stats-block)} + [:div {:class (stl/css :label)} (tr "dashboard.team-projects")] + [:div {:class (stl/css :projects)} + [:span {:class (stl/css :icon)} i/folder] + [:span {:class (stl/css :text)} (tr "labels.num-of-projects" (i18n/c (dec (:projects stats))))]] + [:div {:class (stl/css :files)} + [:span {:class (stl/css :icon)} i/file-html] + [:span {:class (stl/css :text)} (tr "labels.num-of-files" (i18n/c (:files stats)))]]]]]]] + + [:* + [:& header {:section :dashboard-team-settings :team team}] + [:section.dashboard-container.dashboard-team-settings + [:div.team-settings + [:div.horizontal-blocks + [:div.block.info-block + [:div.label (tr "dashboard.team-info")] + [:div.name (:name team)] + [:div.icon + (when can-edit? + [:span.update-overlay {:on-click on-image-click} i/image]) + [:img {:src (cfg/resolve-team-photo-url team)}] + (when can-edit? + [:& file-uploader {:accept "image/jpeg,image/png" + :multi false + :ref finput + :on-selected on-file-selected}])]] + + [:div.block.owner-block + [:div.label (tr "dashboard.team-members")] + [:div.owner + [:span.icon [:img {:src (cfg/resolve-profile-photo-url owner)}]] + [:span.text (str (:name owner) " (" (tr "labels.owner") ")")]] + [:div.summary + [:span.icon i/user] + [:span.text (tr "dashboard.num-of-members" (count members-map))]]] + + [:div.block.stats-block + [:div.label (tr "dashboard.team-projects")] + [:div.projects + [:span.icon i/folder] + [:span.text (tr "labels.num-of-projects" (i18n/c (dec (:projects stats))))]] + [:div.files + [:span.icon i/file-html] + [:span.text (tr "labels.num-of-files" (i18n/c (:files stats)))]]]]]]]))) - [:div.block.owner-block - [:div.label (tr "dashboard.team-members")] - [:div.owner - [:span.icon [:img {:src (cfg/resolve-profile-photo-url owner)}]] - [:span.text (str (:name owner) " (" (tr "labels.owner") ")")]] - [:div.summary - [:span.icon i/user] - [:span.text (tr "dashboard.num-of-members" (count members-map))]]] - [:div.block.stats-block - [:div.label (tr "dashboard.team-projects")] - [:div.projects - [:span.icon i/folder] - [:span.text (tr "labels.num-of-projects" (i18n/c (dec (:projects stats))))]] - [:div.files - [:span.icon i/file-html] - [:span.text (tr "labels.num-of-files" (i18n/c (:files stats)))]]]]]]])) diff --git a/frontend/src/app/main/ui/dashboard/team.scss b/frontend/src/app/main/ui/dashboard/team.scss index b7e2542097..9a1306770d 100644 --- a/frontend/src/app/main/ui/dashboard/team.scss +++ b/frontend/src/app/main/ui/dashboard/team.scss @@ -140,3 +140,1198 @@ } } } + +///// + +@import "common/dependencies/colors"; + +$br2: 2px; +$br3: 3px; +$br4: 4px; +$br8: 8px; +$br6: 6px; +$br12: 12px; +$fs12: 0.75rem; +$fs13: 0.8125rem; +$fs14: 0.875rem; +$fs16: 1rem; +$fs18: 1.125rem; +$fs22: 1.375rem; +$fs24: 1.5rem; +$fs36: 2.25rem; +$fw400: 400; +$fw500: 500; +$fw600: 600; +$fw700: 700; +$lh-088: 0.88; +$lh-115: 1.15; // original $title-lh-sm +$lh-500: 5; // original $title-lh-sm +$size-1: 0.25rem; +$size-2: 0.5rem; +$size-4: 1rem; +$size-5: 1.5rem; +$size-6: 2rem; + +.dashboard-header { + display: flex; + align-items: center; + justify-content: space-between; + background-color: $color-white; + height: 63px; + padding: $size-1 $size-4 $size-1 $size-2; + position: relative; + z-index: 10; + user-select: none; + &.team { + display: grid; + grid-template-columns: 20% 1fr 20%; + } + + .element-name { + margin-right: $size-2; + } + + .btn-secondary { + flex-shrink: 0; + z-index: 10; + height: 32px; + } + + svg { + fill: $color-black; + height: 14px; + margin-right: $size-1; + width: 14px; + } + + nav { + display: flex; + align-items: flex-end; + justify-content: center; + z-index: 1; + + ul { + display: flex; + font-size: $fs14; + justify-content: center; + margin: 0; + } + + li { + a { + display: flex; + align-items: center; + flex-basis: 140px; + border-bottom: 3px solid transparent; + color: $color-gray-30; + height: 40px; + padding: $size-1 $size-5; + font-weight: $fw400; + &:hover { + color: $color-black; + text-decoration: none; + } + } + + //&.active { + // a { + // color: $color-black; + // border-color: $color-primary; + // } + //} + } + } + + .dashboard-title { + display: flex; + align-items: center; + margin-left: 13px; + + h1 { + color: $color-black; + display: flex; + flex-shrink: 0; + font-size: $fs22; + font-weight: $fw600; + z-index: 10; + user-select: all; + } + + .context-menu.is-open { + margin-top: 10px; + } + } + + .icon { + display: flex; + align-items: center; + cursor: pointer; + margin-left: $size-2; + z-index: 10; + + svg { + fill: $color-gray-40; + width: 15px; + height: 15px; + + &:hover { + fill: $color-primary-dark; + } + } + } + + .dashboard-buttons { + display: flex; + justify-content: flex-end; + align-items: center; + } + + .dashboard-header-actions { + display: flex; + } + + .pin-icon { + margin: 0 $size-2 0 $size-5; + background-color: transparent; + border: none; + svg { + fill: $color-gray-20; + } + + &.active { + svg { + fill: $color-gray-50; + } + } + } +} + +.dashboard-header { + background-color: transparent; + .dashboard-title { + h1 { + color: $df-primary; + font-size: 24px; + font-weight: 400; + width: 100%; + text-overflow: ellipsis; + overflow: hidden; + white-space: nowrap; + display: block; + max-width: 700px; + } + } + .icon { + svg { + fill: $df-secondary; + } + } + + // Settings sub-menu + .dashboard-header-options { + li { + a { + font-size: 16px; + color: $df-secondary; + border-color: transparent; + &:hover { + color: $df-primary; + } + } + &.active { + a { + color: $df-primary; + } + } + } + } +} + +.dashboard-container { + background-color: $color-dashboard; + flex: 1 0 0; + margin-right: $size-4; + overflow-y: auto; + width: 100%; + &.dashboard-projects { + user-select: none; + } + &.no-bg { + background-color: transparent; + } + &.dashboard-shared { + width: calc(100vw - 320px); + margin-right: 50px; + } + + &.search { + margin-top: 10px; + } +} + +.dashboard-container { + background-color: transparent; + border-top: 1px solid $db-cuaternary; + + .dashboard-settings { + a { + color: $df-secondary; + } + .form-container { + width: 800px; + margin: 80px auto auto 120px; + form { + width: 468px; + .fields-row { + .custom-input, + .custom-select { + flex-direction: column-reverse; + label { + position: relative; + text-transform: uppercase; + color: $df-primary; + font-size: 11px; + margin-bottom: 12px; + margin-left: -4px; + } + input, + select { + background-color: $db-tertiary; + border-radius: 8px; + border-color: transparent; + color: $df-primary; + padding: 0 15px; + &:focus { + outline: 1px solid $da-primary; + } + ::placeholder { + color: $df-secondary; + } + } + .help-icon { + bottom: 12px; + top: auto; + svg { + fill: $df-secondary; + } + } + &.disabled { + input { + background-color: $db-primary; + border-color: $db-cuaternary; + color: $df-secondary; + } + } + .input-container { + background-color: $db-tertiary; + border-radius: 8px; + border-color: transparent; + margin-top: 22px; + .main-content { + label { + position: absolute; + top: -24px; + } + span { + color: $df-primary; + } + } + &:focus { + border: 1px solid $da-primary; + } + } + textarea { + border-radius: 8px; + padding: 12px 14px; + background-color: $db-tertiary; + color: $df-primary; + border: none; + &:focus { + outline: 1px solid $da-primary; + } + } + } + } + .field-title { + color: $df-primary; + } + .field-title:not(:first-child) { + margin-top: 64px; + } + + .field-text { + color: $df-secondary; + } + button, + .btn-secondary { + width: 100%; + font-size: 11px; + text-transform: uppercase; + background-color: $db-tertiary; + color: $df-primary; + &:hover { + color: $da-primary; + background-color: $db-cuaternary; + } + } + hr { + display: none; + } + } + .links { + margin-top: 12px; + } + } + } + + //Access tokens + .dashboard-access-tokens { + width: 800px; + margin-left: 120px; + margin-top: 80px; + .access-tokens-hero-container { + background-color: transparent; + .access-tokens-hero { + width: 468px; + flex-direction: column; + gap: 32px; + background-color: transparent; + margin: 0; + padding: 0; + .desc { + background-color: transparent; + width: 100%; + h2 { + color: $df-primary; + font-size: 24px; + font-weight: regular; + margin-bottom: 32px; + } + p { + color: $df-secondary; + margin-bottom: 0; + font-size: 14px; + } + } + button { + width: 100%; + font-size: 11px; + text-transform: uppercase; + background-color: $db-tertiary; + color: $df-primary; + &:hover { + color: $da-primary; + background-color: $db-cuaternary; + } + } + } + } + .dashboard-table { + width: 800px; + .table-rows { + padding-top: 0; + .table-row { + font-size: 14px; + min-height: 40px; + height: fit-content; + .name { + color: $df-primary; + max-width: 480px; + overflow: hidden; + text-overflow: ellipsis; + display: -webkit-box; + -webkit-line-clamp: 2; + -webkit-box-orient: vertical; + } + .expiration-date { + color: $df-secondary; + } + } + } + } + .access-tokens-empty { + width: 468px; + border: 1px solid $db-cuaternary; + border-radius: 8px; + margin-top: 32px; + font-size: 14px; + background-color: transparent; + color: $df-secondary; + } + } + + // Team webhooks + &.dashboard-team-webhooks { + width: 800px; + margin-left: 120px; + margin-top: 80px; + border: none; + align-items: flex-start; + .webhooks-hero-container { + width: 468px; + background-color: transparent; + .webhooks-hero { + width: 468px; + flex-direction: column; + gap: 32px; + background-color: transparent; + margin: 0; + padding: 0; + .desc { + background-color: transparent; + width: 100%; + h2 { + color: $df-primary; + font-size: 24px; + font-weight: regular; + margin-bottom: 32px; + } + p { + color: $df-secondary; + margin-bottom: 0; + font-size: 14px; + } + } + .btn-primary { + width: 100%; + font-size: 11px; + text-transform: uppercase; + background-color: $db-tertiary; + color: $df-primary; + &:hover { + color: $da-primary; + background-color: $db-cuaternary; + } + } + } + } + .dashboard-table { + width: 800px; + .table-rows { + padding-top: 0; + .table-row { + font-size: 14px; + min-height: 40px; + height: fit-content; + .name { + color: $df-primary; + max-width: 480px; + } + .expiration-date { + color: $df-secondary; + } + } + } + } + .webhooks-empty { + width: 468px; + border: 1px solid $db-cuaternary; + border-radius: 8px; + margin-top: 32px; + font-size: 14px; + background-color: transparent; + color: $df-secondary; + } + } + + // Members section + .dashboard-table { + .table-header { + background-color: transparent; + color: $df-secondary; + font-size: 12px; + text-transform: uppercase; + } + .table-rows { + .table-row { + background-color: $db-tertiary; + border-radius: 8px; + color: $df-primary; + .rol-selector { + background-color: $db-cuaternary; + border-color: transparent; + border-radius: 8px; + } + } + } + .member-info { + .member-name .you, + .member-email { + color: $df-secondary; + } + } + .status-badge { + border-radius: 8px; + color: $db-primary; + text-transform: uppercase; + } + .empty-invitations { + border: 1px solid $db-cuaternary; + border-radius: 8px; + color: $df-secondary; + } + } + .actions-dropdown, + .options-dropdown { + background-color: $db-tertiary; + border: 1px solid $db-cuaternary; + border-radius: 8px; + min-width: 252px; + + .separator { + border-color: transparent; + margin-top: 10px; + } + + li { + border-radius: 8px; + height: 40px; + margin: 5px; + color: $df-primary; + + &:hover { + background-color: $db-cuaternary; + } + } + + &.options-dropdown { + li { + color: $df-primary; + &.warning { + color: $color-danger; + } + } + } + } +} + +.dashboard-table { + display: flex; + flex-direction: column; + align-items: center; + margin-top: 20px; + font-size: $fs16; + + &.team-members { + margin-bottom: 52px; + } + + &.invitations { + .table-row { + display: grid; + grid-template-columns: 43% 1fr 109px 12px; + } + } + + .table-header { + display: grid; + grid-template-columns: 43% 1fr 109px 12px; + max-width: 1040px; + background-color: $color-white; + color: $color-gray-30; + width: 100%; + height: 40px; + padding: 0px 16px; + } + + .table-rows { + display: flex; + flex-direction: column; + max-width: 1040px; + width: 100%; + margin-top: 16px; + color: $color-black; + } + + .table-row { + display: flex; + width: 100%; + height: 45px; + align-items: center; + padding: 0px 16px; + } + + .table-field { + display: flex; + align-items: center; + + .icon { + padding-left: 10px; + cursor: pointer; + } + } + + svg { + width: 10px; + height: 10px; + fill: $color-black; + } +} + +.dashboard-team-members, +.dashboard-team-invitations, +.dashboard-team-webhooks { + .empty-invitations { + height: 156px; + max-width: 1040px; + width: 100%; + display: flex; + justify-content: center; + align-items: center; + flex-direction: column; + border: 1px dashed $color-gray-20; + margin-top: 16px; + } + .table-header { + user-select: none; + } + + .table-row { + background-color: $color-white; + height: 63px; + &:not(:first-child) { + margin-top: 16px; + } + } + + .table-field { + &.name { + width: 43%; + min-width: 300px; + display: flex; + .member-info { + display: flex; + flex-direction: column; + margin-left: 16px; + .member-name { + font-size: $fs16; + .you { + color: $color-gray-30; + margin-left: 5px; + } + } + .member-email { + color: $color-gray-30; + font-size: $fs12; + } + } + + .member-image { + height: 32px; + width: 32px; + img { + border-radius: 50%; + } + } + } + + &.roles { + flex-grow: 1; + cursor: default; + position: relative; + .rol-label { + user-select: none; + } + .rol-selector { + &.has-priv { + border: 1px solid $color-gray-20; + cursor: pointer; + } + min-width: 160px; + height: 32px; + display: flex; + justify-content: space-between; + align-items: center; + border-radius: $br2; + padding: 3px 8px; + font-size: $fs14; + } + } + + &.actions { + position: relative; + .actions-dropdown { + max-height: 30rem; + min-width: 180px; + } + + svg { + fill: $df-secondary; + } + } + + &.status { + .status-badge { + color: $color-white; + border-radius: $br12; + min-width: 74px; + height: 24px; + display: flex; + justify-content: center; + align-items: center; + + &.pending { + background-color: $color-warning; + } + + &.expired { + background-color: $color-gray-20; + } + + .status-label { + font-size: $fs12; + } + } + } + + &.uri { + flex-grow: 1; + } + + &.active { + min-width: 100px; + } + + &.last-delivery { + display: flex; + justify-content: center; + width: 50px; + position: relative; + .success svg { + fill: $color-primary; + width: 16px; + height: 16px; + } + .failure svg { + fill: $color-warning; + width: 16px; + height: 16px; + } + + .icon-container { + width: 16px; + height: 16px; + overflow-x: visible; + } + + .icon { + padding: 0; + } + } + + .tooltip { + display: none; + position: absolute; + top: -58px; + left: 50%; + transform: translate(-50%, 0); + text-align: center; + + .label { + border-radius: $br3; + color: $color-white; + background-color: $color-black; + white-space: nowrap; + padding: 12px 20px; + } + + .arrow-down { + margin: 0 auto; + width: 0; + height: 0; + border-left: 8px solid transparent; + border-right: 8px solid transparent; + border-top: 8px solid $color-black; + } + } + + .last-delivery-icon:hover { + .tooltip { + display: block; + } + } + } + + .dropdown { + position: absolute; + max-height: 30rem; + overflow-y: auto; + background-color: $color-white; + border-radius: $br4; + box-shadow: 0px 2px 8px rgba(0, 0, 0, 0.25); + z-index: 12; + top: 30px; + left: -151px; + width: 155px; + + hr { + margin: 0; + border-color: $color-gray-10; + } + + li { + display: flex; + align-items: center; + color: $color-gray-60; + cursor: pointer; + font-size: $fs14; + height: 31px; + padding: 5px 16px; + + &.title { + font-weight: $fw600; + cursor: default; + } + + &:hover { + background-color: $color-primary-lighter; + } + } + } +} + +.dashboard-team-settings { + .team-settings { + display: flex; + justify-content: center; + margin-top: 16px; + + svg { + width: 20px; + height: 20px; + } + + .horizontal-blocks { + display: flex; + max-width: 1010px; + justify-content: space-between; + width: 100%; + } + + .block { + display: flex; + max-width: 324px; + width: 324px; + background-color: $color-white; + flex-direction: column; + padding: 12px; + + .label { + font-size: $fs13; + color: $color-gray-30; + } + } + + .info-block { + position: relative; + + .name { + margin-top: 10px; + font-size: $fs24; + color: $color-black; + @include text-ellipsis; + margin-right: 90px; + } + + .icon { + position: absolute; + padding: 15px; + width: 100px; + height: 100px; + right: 0px; + top: 0px; + + img { + border-radius: 50%; + width: 70px; + height: 70px; + } + + .update-overlay { + opacity: 0; + cursor: pointer; + position: absolute; + display: flex; + justify-content: center; + align-items: center; + width: 71px; + height: 71px; + border-radius: 50%; + color: $color-white; + background: $color-primary-dark; + z-index: 14; + + svg { + fill: $color-white; + } + } + + &:hover { + .update-overlay { + opacity: 1; + width: 72px; + height: 72px; + top: 14px; + left: 14px; + } + } + } + } + + .owner-block { + img { + width: 30px; + height: 30px; + border-radius: 50%; + } + + svg { + width: 12px; + height: 12px; + fill: $color-black; + } + + .owner { + margin-top: 5px; + display: flex; + align-items: center; + color: $color-black; + .icon { + margin-right: 12px; + } + } + + .summary { + margin-top: 5px; + color: $color-black; + .icon { + padding: 0px 10px; + margin-right: 12px; + } + } + } + + .stats-block { + svg { + fill: $color-black; + } + + .projects, + .files { + margin-top: 7px; + display: flex; + align-items: center; + color: $color-black; + + .icon { + display: flex; + align-items: center; + padding: 0px 2px; + margin-right: 14px; + } + } + } + } +} + +.dashboard-team-webhooks { + display: flex; + flex-direction: column; + align-items: center; + + .webhooks-hero-container { + max-width: 1000px; + width: 100%; + display: flex; + flex-direction: column; + + .upload-button { + width: 100px; + } + + .btn-secondary { + margin-left: 10px; + } + } + + .webhooks-hero { + font-size: $fs14; + + padding: $size-6; + background-color: $color-white; + margin-top: $size-6; + display: flex; + justify-content: space-between; + + .banner { + background-color: unset; + + display: flex; + + .icon { + display: flex; + align-items: center; + padding-left: 0px; + padding-right: 10px; + svg { + fill: $color-info; + } + } + } + + .desc { + h2 { + margin-bottom: $size-4; + color: $color-black; + } + width: 80%; + color: $color-gray-40; + p { + font-size: $fs16; + } + } + + .btn-primary { + flex-shrink: 0; + } + } + + .webhooks-empty { + text-align: center; + max-width: 1000px; + width: 100%; + padding: $size-6; + display: flex; + flex-direction: column; + justify-content: center; + align-items: center; + border: 1px dashed $color-gray-20; + color: $color-gray-40; + margin-top: 12px; + min-height: 136px; + } +} + +.webhooks-modal { + .action-buttons { + gap: 10px; + + .cancel-button { + border: 1px solid $color-gray-30; + background: $color-canvas; + border-radius: $br3; + padding: 0.5rem 1rem; + cursor: pointer; + margin-right: 8px; + + &:hover { + background: $color-gray-20; + } + } + } + .input-checkbox label { + font-size: $fs14; + color: $color-black; + } + + .explain { + font-size: $fs12; + color: $color-gray-40; + } +} + +.dashboard-team-settings { + .team-settings { + .horizontal-blocks { + flex-direction: column; + gap: 24px; + .block { + background-color: transparent; + .label { + color: $df-secondary; + font-size: 11px; + text-transform: uppercase; + } + .icon { + svg { + fill: $df-secondary; + } + } + .name, + .text { + color: $df-primary; + } + &.info-block { + padding-top: 180px; + .icon { + left: 0; + height: 120px; + width: 120px; + img { + width: 120px; + height: 120px; + } + .update-overlay { + background-color: $da-primary; + height: 120px; + width: 120px; + svg { + fill: $db-primary; + } + } + } + } + } + } + } +} + +.btn-secondary { + background-color: $db-tertiary; + text-transform: uppercase; + border: none; + color: $df-primary; + border-radius: 8px; + + font-size: 0.75rem; + padding: 0 1rem; + cursor: pointer; + display: flex; + justify-content: center; + align-items: center; + + &:hover { + background-color: $db-cuaternary; + color: $da-primary; + text-decoration: none; + svg { + fill: $da-primary; + } + } +} + +.btn-primary { + background-color: $da-tertiary; + border-radius: 8px; + color: $db-primary; + height: 32px; + text-transform: uppercase; + + appearance: none; + align-items: center; + border: none; + cursor: pointer; + display: flex; + font-family: "worksans", sans-serif; + font-size: $fs12; + justify-content: center; + min-width: 25px; + padding: 0 1rem; + transition: all 0.4s; + text-decoration: none; + + &:hover { + background-color: darken($da-tertiary, 10%); + color: $db-primary; + } +} diff --git a/frontend/src/app/main/ui/dashboard/templates.cljs b/frontend/src/app/main/ui/dashboard/templates.cljs index fcc05a9f7c..0bd2394cd9 100644 --- a/frontend/src/app/main/ui/dashboard/templates.cljs +++ b/frontend/src/app/main/ui/dashboard/templates.cljs @@ -5,6 +5,7 @@ ;; Copyright (c) KALEIDOS INC (ns app.main.ui.dashboard.templates + (:require-macros [app.main.style :as stl]) (:require [app.common.data.macros :as dm] [app.common.math :as mth] @@ -15,6 +16,7 @@ [app.main.data.users :as du] [app.main.refs :as refs] [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 :refer [tr]] @@ -57,7 +59,8 @@ (mf/defc title {::mf/wrap-props false} [{:keys [collapsed]}] - (let [on-click + (let [new-css-system (mf/use-ctx ctx/new-css-system) + on-click (mf/use-fn (mf/deps collapsed) (fn [_event] @@ -73,17 +76,27 @@ (dom/prevent-default event) (on-click event))))] - [:div.title - [:button {:tab-index "0" - :on-click on-click - :on-key-down on-key-down} - [:span (tr "dashboard.libraries-and-templates")] - [:span.icon (if ^boolean collapsed i/arrow-up i/arrow-down)]]])) + (if new-css-system + [:div {:class (stl/css :title)} + [:button {:tab-index "0" + :on-click on-click + :on-key-down on-key-down} + [:span (tr "dashboard.libraries-and-templates")] + [:span {:class (stl/css :icon)} (if ^boolean collapsed i/arrow-up i/arrow-down)]]] + + ;; OLD + [:div.title + [:button {:tab-index "0" + :on-click on-click + :on-key-down on-key-down} + [:span (tr "dashboard.libraries-and-templates")] + [:span.icon (if ^boolean collapsed i/arrow-up i/arrow-down)]]]))) (mf/defc card-item {::mf/wrap-props false} [{:keys [item index is-visible collapsed on-import]}] - (let [id (dm/str "card-container-" index) + (let [new-css-system (mf/use-ctx ctx/new-css-system) + id (dm/str "card-container-" index) thb (assoc cf/public-uri :path (dm/str "/images/thumbnails/template-" (:id item) ".jpg")) on-click @@ -100,23 +113,41 @@ (dom/stop-propagation event) (on-import item event))))] - [:a.card-container - {:tab-index (if (or (not is-visible) collapsed) "-1" "0") - :id id - :data-index index - :on-click on-click - :on-key-down on-key-down} - [:div.template-card - [:div.img-container - [:img {:src (dm/str thb) - :alt (:name item)}]] - [:div.card-name [:span (:name item)] - [:span.icon i/download]]]])) + (if new-css-system + [:a + {:class (stl/css :card-container) + :tab-index (if (or (not is-visible) collapsed) "-1" "0") + :id id + :data-index index + :on-click on-click + :on-key-down on-key-down} + [:div {:class (stl/css :template-card)} + [:div {:class (stl/css :img-container)} + [:img {:src (dm/str thb) + :alt (:name item)}]] + [:div {:class (stl/css :card-name)} + [:span (:name item)] + [:span {:class (stl/css :icon)} i/download]]]] + + ;; OLD + [:a.card-container + {:tab-index (if (or (not is-visible) collapsed) "-1" "0") + :id id + :data-index index + :on-click on-click + :on-key-down on-key-down} + [:div.template-card + [:div.img-container + [:img {:src (dm/str thb) + :alt (:name item)}]] + [:div.card-name [:span (:name item)] + [:span.icon i/download]]]]))) (mf/defc card-item-link {::mf/wrap-props false} [{:keys [total is-visible collapsed section]}] - (let [id (dm/str "card-container-" total) + (let [new-css-system (mf/use-ctx ctx/new-css-system) + id (dm/str "card-container-" total) on-click (mf/use-fn @@ -134,23 +165,39 @@ (dom/stop-propagation event) (on-click event))))] - [:div.card-container - [:div.template-card - [:div.img-container - [:a {:id id - :tab-index (if (or (not is-visible) collapsed) "-1" "0") - :href "https://penpot.app/libraries-templates.html" - :target "_blank" - :on-click on-click - :on-key-down on-key-down} - [:div.template-link - [:div.template-link-title (tr "dashboard.libraries-and-templates")] - [:div.template-link-text (tr "dashboard.libraries-and-templates.explore")]]]]]])) + (if new-css-system + [:div {:class (stl/css :card-container)} + [:div {:class (stl/css :template-card)} + [:div {:class (stl/css :img-container)} + [:a {:id id + :tab-index (if (or (not is-visible) collapsed) "-1" "0") + :href "https://penpot.app/libraries-templates.html" + :target "_blank" + :on-click on-click + :on-key-down on-key-down} + [:div {:class (stl/css :template-link)} + [:div {:class (stl/css :template-link-title)} (tr "dashboard.libraries-and-templates")] + [:div {:class (stl/css :template-link-text)} (tr "dashboard.libraries-and-templates.explore")]]]]]] + + ;; OLD + [:div.card-container + [:div.template-card + [:div.img-container + [:a {:id id + :tab-index (if (or (not is-visible) collapsed) "-1" "0") + :href "https://penpot.app/libraries-templates.html" + :target "_blank" + :on-click on-click + :on-key-down on-key-down} + [:div.template-link + [:div.template-link-title (tr "dashboard.libraries-and-templates")] + [:div.template-link-text (tr "dashboard.libraries-and-templates.explore")]]]]]]))) (mf/defc templates-section {::mf/wrap-props false} [{:keys [default-project-id profile project-id team-id content-width]}] - (let [templates (mf/deref builtin-templates) + (let [new-css-system (mf/use-ctx ctx/new-css-system) + templates (mf/deref builtin-templates) templates (mf/with-memo [templates] (filterv #(not= (:id %) "tutorial-for-beginners") templates)) @@ -234,42 +281,86 @@ (when (and profile (not collapsed)) (st/emit! (dd/fetch-builtin-templates)))) - [:div.dashboard-templates-section - {:class (when ^boolean collapsed "collapsed")} - [:& title {:collapsed collapsed}] + (if new-css-system + [:div + {:class (stl/css-case :dashboard-templates-section true + :collapsed collapsed)} + [:& title {:collapsed collapsed}] - [:div.content {:ref content-ref - :style {:left card-offset - :width (dm/str container-size "px")}} + [:div {:class (stl/css :content) + :ref content-ref + :style {:left card-offset + :width (dm/str container-size "px")}} - (for [index (range (count templates))] - [:& card-item - {:on-import on-import-template - :item (nth templates index) - :index index - :key index - :is-visible (and (>= index first-card) - (<= index last-card)) - :collapsed collapsed}]) + (for [index (range (count templates))] + [:& card-item + {:on-import on-import-template + :item (nth templates index) + :index index + :key index + :is-visible (and (>= index first-card) + (<= index last-card)) + :collapsed collapsed}]) - [:& card-item-link - {:is-visible (and (>= total first-card) (<= total last-card)) - :collapsed collapsed - :section section - :total total}]] + [:& card-item-link + {:is-visible (and (>= total first-card) (<= total last-card)) + :collapsed collapsed + :section section + :total total}]] - (when (< card-offset 0) - [:button.button.left - {:tab-index (if ^boolean collapsed "-1" "0") - :on-click on-move-left - :on-key-down on-move-left-key-down} - i/go-prev]) + (when (< card-offset 0) + [:button + {:class (stl/css :button :left) + :tab-index (if ^boolean collapsed "-1" "0") + :on-click on-move-left + :on-key-down on-move-left-key-down} + i/go-prev]) - (when more-cards - [:button.button.right - {:tab-index (if collapsed "-1" "0") - :on-click on-move-right - :aria-label (tr "labels.next") - :on-key-down on-move-right-key-down} - i/go-next])])) + (when more-cards + [:button + {:class (stl/css :button :right) + :tab-index (if collapsed "-1" "0") + :on-click on-move-right + :aria-label (tr "labels.next") + :on-key-down on-move-right-key-down} + i/go-next])] + ;; OLD + [:div.dashboard-templates-section + {:class (when ^boolean collapsed "collapsed")} + [:& title {:collapsed collapsed}] + + [:div.content {:ref content-ref + :style {:left card-offset + :width (dm/str container-size "px")}} + + (for [index (range (count templates))] + [:& card-item + {:on-import on-import-template + :item (nth templates index) + :index index + :key index + :is-visible (and (>= index first-card) + (<= index last-card)) + :collapsed collapsed}]) + + [:& card-item-link + {:is-visible (and (>= total first-card) (<= total last-card)) + :collapsed collapsed + :section section + :total total}]] + + (when (< card-offset 0) + [:button.button.left + {:tab-index (if ^boolean collapsed "-1" "0") + :on-click on-move-left + :on-key-down on-move-left-key-down} + i/go-prev]) + + (when more-cards + [:button.button.right + {:tab-index (if collapsed "-1" "0") + :on-click on-move-right + :aria-label (tr "labels.next") + :on-key-down on-move-right-key-down} + i/go-next])]))) diff --git a/frontend/src/app/main/ui/dashboard/templates.scss b/frontend/src/app/main/ui/dashboard/templates.scss new file mode 100644 index 0000000000..8f6ba747f2 --- /dev/null +++ b/frontend/src/app/main/ui/dashboard/templates.scss @@ -0,0 +1,246 @@ +// 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 "common/dependencies/colors"; + +$br10: 10px; +$lh-normal: normal; +$fs18: 1.125rem; +$fw600: 600; +$fs16: 1rem; +$br5: 5px; +$fw500: 500; +$fs14: 0.875rem; +$fs12: 0.75rem; +$size-2: 0.5rem; + +.dashboard-templates-section { + position: absolute; + display: flex; + flex-direction: column; + justify-content: flex-end; + bottom: 0; + width: 100%; + height: 228px; + transition: bottom 300ms; + pointer-events: none; + &.collapsed { + bottom: -228px; + transition: bottom 300ms; + } + + .title { + pointer-events: all; + width: fit-content; + top: -56px; + right: -28px; + text-align: right; + height: 56px; + position: absolute; + button { + border: none; + cursor: pointer; + height: 58px; + display: inline-flex; + align-items: center; + border-top: 2px solid #e4e4e4; + border-left: 2px solid #e4e4e4; + border-right: 2px solid #e4e4e4; + border-top-left-radius: $br10; + border-top-right-radius: $br10; + margin-right: 30px; + background-color: $color-white; + position: relative; + z-index: 1; + span { + display: inline-block; + vertical-align: middle; + line-height: $lh-normal; + font-size: $fs18; + font-weight: $fw600; + color: $color-black; + margin-left: 18px; + margin-right: 10px; + &.icon { + margin-left: 10px; + margin-right: 16px; + } + } + svg { + width: 12px; + height: 12px; + fill: $df-secondary; + } + } + } + + .button { + position: absolute; + top: 133px; + border: 2px solid #e0e4e9; + border-radius: 50%; + text-align: center; + width: 35px; + height: 35px; + cursor: pointer; + background-color: $color-white; + display: flex; + align-items: center; + justify-content: center; + pointer-events: all; + svg { + width: 12px; + height: 12px; + fill: $df-secondary; + } + + &.left { + left: 0; + margin-left: 43px; + } + + &.right { + right: 0; + margin-right: 43px; + } + + &:hover { + border: 2px solid $color-primary; + } + } + + .content { + pointer-events: all; + background-color: $color-white; + width: 200%; + height: 229px; + border-top: 2px solid #e4e4e4; + border-left: 2px solid #e4e4e4; + margin-left: 5px; + position: absolute; + + .card-container { + width: 275px; + margin-top: 20px; + display: inline-block; + text-align: center; + vertical-align: top; + background-color: transparent; + border: none; + padding: 0; + } + + .template-card { + display: inline-block; + width: 255px; + font-size: $fs16; + color: #181a22; + cursor: pointer; + .img-container { + width: 100%; + height: 135px; + margin-bottom: 15px; + border-radius: $br5; + border: 2px solid #e0e4e9; + display: flex; + justify-content: center; + flex-direction: column; + } + + .card-name { + padding: 0 5px; + display: flex; + justify-content: space-between; + height: 23px; + svg { + width: 16px; + height: 16px; + fill: $df-secondary; + } + span { + font-weight: $fw500; + font-size: $fs14; + } + } + + .template-link { + border: 2px solid transparent; + margin: 30px; + padding: 32px 0; + } + + .template-link-title { + font-size: $fs14; + font-weight: $fw600; + color: $color-gray-60; + } + + .template-link-text { + font-size: $fs12; + margin-top: $size-2; + color: $color-gray-50; + } + + &:hover { + .img-container { + border: 2px solid $color-primary; + } + } + } + } +} + +.dashboard-templates-section { + .title { + right: -24px; + button { + background-color: $db-cuaternary; + border: none; + span { + color: $df-primary; + font-weight: 400; + } + } + } + .content { + border-top-left-radius: 8px; + border: none; + background-color: $db-cuaternary; + + .template-card { + color: $df-primary; + padding: 0.2rem 0.3rem 1rem 0.3rem; + border-radius: 8px; + .img-container { + border: none; + img { + border-radius: 4px; + } + } + .card-name { + span { + font-size: 16px; + } + } + .template-link { + .template-link-title { + color: $df-primary; + font-weight: 400; + } + .template-link-text { + color: $df-secondary; + } + } + + &:hover { + background-color: $db-tertiary; + .img-container { + border: none; + } + } + } + } +} diff --git a/frontend/src/app/main/ui/settings.cljs b/frontend/src/app/main/ui/settings.cljs index e15d96b5da..7fdcaef887 100644 --- a/frontend/src/app/main/ui/settings.cljs +++ b/frontend/src/app/main/ui/settings.cljs @@ -5,6 +5,7 @@ ;; Copyright (c) KALEIDOS INC (ns app.main.ui.settings + (:require-macros [app.main.style :as stl]) (:require [app.main.refs :as refs] [app.main.store :as st] @@ -25,9 +26,16 @@ (mf/defc header {::mf/wrap [mf/memo]} [] - [:header.dashboard-header - [:div.dashboard-title - [:h1 {:data-test "account-title"} (tr "dashboard.your-account-title")]]]) + (let [new-css-system (mf/use-ctx ctx/new-css-system)] + (if new-css-system + [:header {:class (stl/css :dashboard-header)} + [:div {:class (stl/css :dashboard-title)} + [:h1 {:data-test "account-title"} (tr "dashboard.your-account-title")]]] + + ;; OLD + [:header.dashboard-header + [:div.dashboard-title + [:h1 {:data-test "account-title"} (tr "dashboard.your-account-title")]]]))) (mf/defc settings [{:keys [route] :as props}] @@ -40,28 +48,53 @@ #(when (nil? profile) (st/emit! (rt/nav :auth-login)))) - [:section {:class (dom/classnames :dashboard-layout (not new-css-system) - :dashboard-layout-refactor new-css-system)} - [:& sidebar {:profile profile - :locale locale - :section section}] + (if new-css-system + [:section {:class (stl/css :dashboard-layout-refactor :dashboard)} + [:& sidebar {:profile profile + :locale locale + :section section}] - [:div.dashboard-content - [:& header] - [:section.dashboard-container - (case section - :settings-profile - [:& profile-page {:locale locale}] + [:div {:class (stl/css :dashboard-content)} + [:& header] + [:section {:class (stl/css :dashboard-container)} + (case section + :settings-profile + [:& profile-page {:locale locale}] - :settings-feedback - [:& feedback-page] + :settings-feedback + [:& feedback-page] - :settings-password - [:& password-page {:locale locale}] + :settings-password + [:& password-page {:locale locale}] - :settings-options - [:& options-page {:locale locale}] + :settings-options + [:& options-page {:locale locale}] - :settings-access-tokens - [:& access-tokens-page])]]])) + :settings-access-tokens + [:& access-tokens-page])]]] + ;; OLD + [:section {:class (dom/classnames :dashboard-layout (not new-css-system) + :dashboard-layout-refactor new-css-system)} + [:& sidebar {:profile profile + :locale locale + :section section}] + + [:div.dashboard-content + [:& header] + [:section.dashboard-container + (case section + :settings-profile + [:& profile-page {:locale locale}] + + :settings-feedback + [:& feedback-page] + + :settings-password + [:& password-page {:locale locale}] + + :settings-options + [:& options-page {:locale locale}] + + :settings-access-tokens + [:& access-tokens-page])]]]))) diff --git a/frontend/src/app/main/ui/settings.scss b/frontend/src/app/main/ui/settings.scss new file mode 100644 index 0000000000..2f907fb3fd --- /dev/null +++ b/frontend/src/app/main/ui/settings.scss @@ -0,0 +1,697 @@ +@import "common/dependencies/colors"; + +$fs14: 0.875rem; +$fs22: 1.5rem; +$fs24: 1.5rem; +$lh-500: 5; +$fs12: 0.75rem; +$fs16: 1rem; +$fw400: 400; +$fw600: 600; +$size-1: 0.25rem; +$size-2: 0.5rem; +$size-3: 0.75rem; +$size-4: 1rem; +$size-5: 1.5rem; +$size-6: 2rem; +$br3: 3px; +$br4: 4px; +$br5: 5px; +$fw700: 700; + +.dashboard { + background-color: $db-primary; + display: grid; + grid-template-rows: 50px 1fr; + grid-template-columns: 40px 256px 1fr; + height: 100vh; +} + +.dashboard-content { + display: flex; + flex-direction: column; + position: relative; + grid-row: 1 / span 2; + padding: 1rem 1rem 0 0; +} + +.dashboard-header { + display: flex; + align-items: center; + justify-content: space-between; + background-color: $color-white; + height: 63px; + padding: $size-1 $size-4 $size-1 $size-2; + position: relative; + z-index: 10; + user-select: none; + &.team { + display: grid; + grid-template-columns: 20% 1fr 20%; + } + + .element-name { + margin-right: $size-2; + } + + .btn-secondary { + flex-shrink: 0; + z-index: 10; + height: 32px; + svg { + height: 16px; + width: 16px; + } + } + + svg { + fill: $color-black; + height: 14px; + margin-right: $size-1; + width: 14px; + } + + nav { + display: flex; + align-items: flex-end; + justify-content: center; + z-index: 1; + + ul { + display: flex; + font-size: $fs14; + justify-content: center; + margin: 0; + } + + li { + a { + display: flex; + align-items: center; + flex-basis: 140px; + border-bottom: 3px solid transparent; + color: $color-gray-30; + height: 40px; + padding: $size-1 $size-5; + font-weight: $fw400; + &:hover { + color: $color-black; + text-decoration: none; + } + } + + &.active { + a { + color: $color-black; + border-color: $color-primary; + } + } + } + } + + .dashboard-title { + display: flex; + align-items: center; + margin-left: 13px; + + h1 { + color: $color-black; + display: flex; + flex-shrink: 0; + font-size: $fs22; + font-weight: $fw600; + z-index: 10; + user-select: all; + } + + .context-menu.is-open { + margin-top: 10px; + } + } + + .icon { + display: flex; + align-items: center; + cursor: pointer; + margin-left: $size-2; + z-index: 10; + + svg { + fill: $color-gray-40; + width: 15px; + height: 15px; + + &:hover { + fill: $color-primary-dark; + } + } + } + + .dashboard-buttons { + display: flex; + justify-content: flex-end; + align-items: center; + } + + .dashboard-header-actions { + display: flex; + } + + .pin-icon { + margin: 0 $size-2 0 $size-5; + background-color: transparent; + border: none; + svg { + fill: $color-gray-20; + } + + &.active { + svg { + fill: $color-gray-50; + } + } + } +} + +.dashboard-header { + background-color: transparent; + .dashboard-title { + h1 { + color: $df-primary; + font-size: 24px; + font-weight: 400; + width: 100%; + text-overflow: ellipsis; + overflow: hidden; + white-space: nowrap; + display: block; + max-width: 700px; + } + } + .icon { + svg { + fill: $df-secondary; + } + } + + // Settings sub-menu + .dashboard-header-options { + li { + a { + font-size: 16px; + color: $df-secondary; + border-color: transparent; + &:hover { + color: $df-primary; + } + } + &.active { + a { + color: $df-primary; + } + } + } + } +} + +.dashboard-container { + background-color: $color-dashboard; + flex: 1 0 0; + margin-right: $size-4; + overflow-y: auto; + width: 100%; + &.dashboard-projects { + user-select: none; + } + &.no-bg { + background-color: transparent; + } + &.dashboard-shared { + width: calc(100vw - 320px); + margin-right: 50px; + } + + &.search { + margin-top: 10px; + } +} + +.dashboard-container { + background-color: transparent; + border-top: 1px solid $db-cuaternary; + + .dashboard-settings { + a { + color: $df-secondary; + } + .form-container { + width: 800px; + margin: 80px auto auto 120px; + form { + width: 468px; + .fields-row { + .custom-input, + .custom-select { + flex-direction: column-reverse; + label { + position: relative; + text-transform: uppercase; + color: $df-primary; + font-size: 11px; + margin-bottom: 12px; + margin-left: -4px; + } + input, + select { + background-color: $db-tertiary; + border-radius: 8px; + border-color: transparent; + color: $df-primary; + padding: 0 15px; + &:focus { + outline: 1px solid $da-primary; + } + ::placeholder { + color: $df-secondary; + } + } + .help-icon { + bottom: 12px; + top: auto; + svg { + fill: $df-secondary; + } + } + &.disabled { + input { + background-color: $db-primary; + border-color: $db-cuaternary; + color: $df-secondary; + } + } + .input-container { + background-color: $db-tertiary; + border-radius: 8px; + border-color: transparent; + margin-top: 22px; + .main-content { + label { + position: absolute; + top: -24px; + } + span { + color: $df-primary; + } + } + &:focus { + border: 1px solid $da-primary; + } + } + textarea { + border-radius: 8px; + padding: 12px 14px; + background-color: $db-tertiary; + color: $df-primary; + border: none; + &:focus { + outline: 1px solid $da-primary; + } + } + } + } + .field-title { + color: $df-primary; + } + .field-title:not(:first-child) { + margin-top: 64px; + } + + .field-text { + color: $df-secondary; + } + button, + .btn-secondary { + width: 100%; + font-size: 11px; + text-transform: uppercase; + background-color: $db-tertiary; + color: $df-primary; + &:hover { + color: $da-primary; + background-color: $db-cuaternary; + } + } + hr { + display: none; + } + } + .links { + margin-top: 12px; + } + } + } + + //Access tokens + .dashboard-access-tokens { + width: 800px; + margin-left: 120px; + margin-top: 80px; + .access-tokens-hero-container { + background-color: transparent; + .access-tokens-hero { + width: 468px; + flex-direction: column; + gap: 32px; + background-color: transparent; + margin: 0; + padding: 0; + .desc { + background-color: transparent; + width: 100%; + h2 { + color: $df-primary; + font-size: 24px; + font-weight: regular; + margin-bottom: 32px; + } + p { + color: $df-secondary; + margin-bottom: 0; + font-size: 14px; + } + } + button { + width: 100%; + font-size: 11px; + text-transform: uppercase; + background-color: $db-tertiary; + color: $df-primary; + &:hover { + color: $da-primary; + background-color: $db-cuaternary; + } + } + } + } + .dashboard-table { + width: 800px; + .table-rows { + padding-top: 0; + .table-row { + font-size: 14px; + min-height: 40px; + height: fit-content; + .name { + color: $df-primary; + max-width: 480px; + overflow: hidden; + text-overflow: ellipsis; + display: -webkit-box; + -webkit-line-clamp: 2; + -webkit-box-orient: vertical; + } + .expiration-date { + color: $df-secondary; + } + } + } + } + .access-tokens-empty { + width: 468px; + border: 1px solid $db-cuaternary; + border-radius: 8px; + margin-top: 32px; + font-size: 14px; + background-color: transparent; + color: $df-secondary; + } + } + + // Team webhooks + &.dashboard-team-webhooks { + width: 800px; + margin-left: 120px; + margin-top: 80px; + border: none; + align-items: flex-start; + .webhooks-hero-container { + width: 468px; + background-color: transparent; + .webhooks-hero { + width: 468px; + flex-direction: column; + gap: 32px; + background-color: transparent; + margin: 0; + padding: 0; + .desc { + background-color: transparent; + width: 100%; + h2 { + color: $df-primary; + font-size: 24px; + font-weight: regular; + margin-bottom: 32px; + } + p { + color: $df-secondary; + margin-bottom: 0; + font-size: 14px; + } + } + .btn-primary { + width: 100%; + font-size: 11px; + text-transform: uppercase; + background-color: $db-tertiary; + color: $df-primary; + &:hover { + color: $da-primary; + background-color: $db-cuaternary; + } + } + } + } + .dashboard-table { + width: 800px; + .table-rows { + padding-top: 0; + .table-row { + font-size: 14px; + min-height: 40px; + height: fit-content; + .name { + color: $df-primary; + max-width: 480px; + } + .expiration-date { + color: $df-secondary; + } + } + } + } + .webhooks-empty { + width: 468px; + border: 1px solid $db-cuaternary; + border-radius: 8px; + margin-top: 32px; + font-size: 14px; + background-color: transparent; + color: $df-secondary; + } + } + + // Members section + .dashboard-table { + .table-header { + background-color: transparent; + color: $df-secondary; + font-size: 12px; + text-transform: uppercase; + } + .table-rows { + .table-row { + background-color: $db-tertiary; + border-radius: 8px; + color: $df-primary; + .rol-selector { + background-color: $db-cuaternary; + border-color: transparent; + border-radius: 8px; + } + } + } + .member-info { + .member-name .you, + .member-email { + color: $df-secondary; + } + } + .status-badge { + border-radius: 8px; + color: $db-primary; + text-transform: uppercase; + } + .empty-invitations { + border: 1px solid $db-cuaternary; + border-radius: 8px; + color: $df-secondary; + } + } + .actions-dropdown, + .options-dropdown { + background-color: $db-tertiary; + border: 1px solid $db-cuaternary; + border-radius: 8px; + min-width: 252px; + + .separator { + border-color: transparent; + margin-top: 10px; + } + + li { + border-radius: 8px; + height: 40px; + margin: 5px; + color: $df-primary; + + &:hover { + background-color: $db-cuaternary; + } + } + + &.options-dropdown { + li { + color: $df-primary; + &.warning { + color: $color-danger; + } + } + } + } +} + +.dashboard-settings { + display: flex; + width: 100%; + justify-content: center; + align-items: center; + + .form-container { + margin-top: 50px; + display: flex; + max-width: 368px; + margin-bottom: 2rem; + width: 100%; + + &.two-columns { + max-width: 536px; + justify-content: space-between; + flex-direction: row; + } + + h2 { + margin-bottom: 1rem; + } + } + + .avatar-form { + display: flex; + flex-direction: column; + width: 120px; + min-width: 120px; + + img { + border-radius: 50%; + flex-shrink: 0; + height: 120px; + margin-right: $size-4; + width: 120px; + } + + .image-change-field { + position: relative; + width: 120px; + height: 120px; + + .update-overlay { + opacity: 0; + cursor: pointer; + position: absolute; + width: 121px; + height: 121px; + border-radius: 50%; + font-size: $fs24; + color: $color-white; + line-height: $lh-500; // Original value was 120px; 120px/24px = 500% => $lh-500 + text-align: center; + background: $color-primary-dark; + z-index: 14; + } + + input[type="file"] { + width: 120px; + height: 120px; + position: absolute; + opacity: 0; + cursor: pointer; + top: 0; + z-index: 15; + } + + &:hover { + .update-overlay { + opacity: 0.8; + } + } + } + } + + .profile-form { + display: flex; + flex-direction: column; + max-width: 368px; + width: 100%; + + .newsletter-subs { + border-bottom: 1px solid $color-gray-20; + border-top: 1px solid $color-gray-20; + padding: 30px 0; + margin-bottom: 31px; + + .newsletter-title { + font-family: "worksans", sans-serif; + color: $color-gray-30; + font-size: $fs14; + } + + label { + font-family: "worksans", sans-serif; + color: $color-gray-60; + font-size: $fs12; + margin-right: -17px; + margin-bottom: 13px; + } + + .info { + font-family: "worksans", sans-serif; + color: $color-gray-30; + font-size: $fs12; + margin-bottom: 8px; + } + + .input-checkbox label { + align-items: flex-start; + } + } + } + + .options-form, + .password-form { + h2 { + font-size: $fs14; + margin-bottom: 20px; + } + } +} diff --git a/frontend/src/app/main/ui/settings/access_tokens.cljs b/frontend/src/app/main/ui/settings/access_tokens.cljs index 617b76e60b..5de70c98c3 100644 --- a/frontend/src/app/main/ui/settings/access_tokens.cljs +++ b/frontend/src/app/main/ui/settings/access_tokens.cljs @@ -247,20 +247,35 @@ (mf/defc access-tokens-hero [] - (let [on-click (mf/use-fn #(st/emit! (modal/show :access-token {})))] - [:div.access-tokens-hero-container - [:div.access-tokens-hero - [:div.desc - [:h2 (tr "dashboard.access-tokens.personal")] - [:p (tr "dashboard.access-tokens.personal.description")]] + (let [new-css-system (mf/use-ctx ctx/new-css-system) + on-click (mf/use-fn #(st/emit! (modal/show :access-token {})))] + (if new-css-system + [:div {:class (stl/css :access-tokens-hero-container)} + [:div {:class (stl/css :access-tokens-hero)} + [:div {:class (stl/css :desc)} + [:h2 (tr "dashboard.access-tokens.personal")] + [:p (tr "dashboard.access-tokens.personal.description")]] - [:button.btn-primary - {:on-click on-click} - [:span (tr "dashboard.access-tokens.create")]]]])) + [:button + {:class (stl/css :btn-primary) + :on-click on-click} + [:span (tr "dashboard.access-tokens.create")]]]] + + ;; OLD + [:div.access-tokens-hero-container + [:div.access-tokens-hero + [:div.desc + [:h2 (tr "dashboard.access-tokens.personal")] + [:p (tr "dashboard.access-tokens.personal.description")]] + + [:button.btn-primary + {:on-click on-click} + [:span (tr "dashboard.access-tokens.create")]]]]))) (mf/defc access-token-actions [{:keys [on-delete]}] - (let [local (mf/use-state {:menu-open false}) + (let [new-css-system (mf/use-ctx ctx/new-css-system) + local (mf/use-state {:menu-open false}) show? (:menu-open @local) options (mf/with-memo [on-delete] [{:option-name (tr "labels.delete") @@ -278,28 +293,50 @@ (dom/prevent-default event) (swap! local assoc :menu-open true)))] - [:div.icon - {:tab-index "0" - :ref menu-ref - :on-click on-menu-click - :on-key-down (fn [event] - (when (kbd/enter? event) - (dom/stop-propagation event) - (on-menu-click event)))} - i/actions - [:& context-menu-a11y - {:on-close on-menu-close - :show show? - :fixed? true - :min-width? true - :top "auto" - :left "auto" - :options options}]])) + (if new-css-system + [:div + {:class (stl/css :icon) + :tab-index "0" + :ref menu-ref + :on-click on-menu-click + :on-key-down (fn [event] + (when (kbd/enter? event) + (dom/stop-propagation event) + (on-menu-click event)))} + i/actions + [:& context-menu-a11y + {:on-close on-menu-close + :show show? + :fixed? true + :min-width? true + :top "auto" + :left "auto" + :options options}]] + + ;; OLD + [:div.icon + {:tab-index "0" + :ref menu-ref + :on-click on-menu-click + :on-key-down (fn [event] + (when (kbd/enter? event) + (dom/stop-propagation event) + (on-menu-click event)))} + i/actions + [:& context-menu-a11y + {:on-close on-menu-close + :show show? + :fixed? true + :min-width? true + :top "auto" + :left "auto" + :options options}]]))) (mf/defc access-token-item {::mf/wrap [mf/memo]} [{:keys [token] :as props}] - (let [locale (mf/deref i18n/locale) + (let [new-css-system (mf/use-ctx ctx/new-css-system) + locale (mf/deref i18n/locale) expires-at (:expires-at token) expires-txt (some-> expires-at (dt/format-date-locale {:locale locale})) expired? (and (some? expires-at) (> (dt/now) expires-at)) @@ -323,36 +360,67 @@ :accept-label (tr "modals.delete-acces-token.accept") :on-accept delete-fn}))))] - [:div.table-row - [:div.table-field.name - (str (:name token))] - [:div.table-field.expiration-date - [:span.content {:class (when expired? "expired")} - (cond - (nil? expires-at) (tr "dashboard.access-tokens.no-expiration") - expired? (tr "dashboard.access-tokens.expired-on" expires-txt) - :else (tr "dashboard.access-tokens.expires-on" expires-txt))]] - [:div.table-field.actions - [:& access-token-actions - {:on-delete on-delete}]]])) + (if new-css-system + [:div {:class (stl/css :table-row)} + [:div {:class (stl/css :table-field :name)} + (str (:name token))] + + [:div {:class (stl/css :table-field :expiration-date)} + [:span {:class (stl/css-case :expired expired? :content true)} + (cond + (nil? expires-at) (tr "dashboard.access-tokens.no-expiration") + expired? (tr "dashboard.access-tokens.expired-on" expires-txt) + :else (tr "dashboard.access-tokens.expires-on" expires-txt))]] + [:div {:class (stl/css :table-field :actions)} + [:& access-token-actions + {:on-delete on-delete}]]] + + ;; OLD + [:div.table-row + [:div.table-field.name + (str (:name token))] + [:div.table-field.expiration-date + [:span.content {:class (when expired? "expired")} + (cond + (nil? expires-at) (tr "dashboard.access-tokens.no-expiration") + expired? (tr "dashboard.access-tokens.expired-on" expires-txt) + :else (tr "dashboard.access-tokens.expires-on" expires-txt))]] + [:div.table-field.actions + [:& access-token-actions + {:on-delete on-delete}]]]))) (mf/defc access-tokens-page [] - (mf/with-effect [] - (dom/set-html-title (tr "title.settings.access-tokens")) - (st/emit! (du/fetch-access-tokens))) + (let [new-css-system (mf/use-ctx ctx/new-css-system) + tokens (mf/deref tokens-ref)] + (mf/with-effect [] + (dom/set-html-title (tr "title.settings.access-tokens")) + (st/emit! (du/fetch-access-tokens))) - (let [tokens (mf/deref tokens-ref)] - [:div.dashboard-access-tokens - [:div - [:& access-tokens-hero] - (if (empty? tokens) - [:div.access-tokens-empty - [:div (tr "dashboard.access-tokens.empty.no-access-tokens")] - [:div (tr "dashboard.access-tokens.empty.add-one")]] - [:div.dashboard-table - [:div.table-rows - (for [token tokens] - [:& access-token-item {:token token :key (:id token)}])]])]])) + (if new-css-system + [:div {:class (stl/css :dashboard-access-tokens)} + [:div + [:& access-tokens-hero] + (if (empty? tokens) + [:div {:class (stl/css :access-tokens-empty)} + [:div (tr "dashboard.access-tokens.empty.no-access-tokens")] + [:div (tr "dashboard.access-tokens.empty.add-one")]] + [:div {:class (stl/css :dashboard-table)} + [:div {:class (stl/css :table-rows)} + (for [token tokens] + [:& access-token-item {:token token :key (:id token)}])]])]] + + ;; OLD + [:div.dashboard-access-tokens + [:div + [:& access-tokens-hero] + (if (empty? tokens) + [:div.access-tokens-empty + [:div (tr "dashboard.access-tokens.empty.no-access-tokens")] + [:div (tr "dashboard.access-tokens.empty.add-one")]] + [:div.dashboard-table + [:div.table-rows + (for [token tokens] + [:& access-token-item {:token token :key (:id token)}])]])]]))) diff --git a/frontend/src/app/main/ui/settings/access_tokens.scss b/frontend/src/app/main/ui/settings/access_tokens.scss index a9d63c3def..fd76557f71 100644 --- a/frontend/src/app/main/ui/settings/access_tokens.scss +++ b/frontend/src/app/main/ui/settings/access_tokens.scss @@ -80,3 +80,849 @@ } } } + +////// + +@import "common/dependencies/colors"; + +$br3: 3px; +$br4: 4px; +$br8: 8px; +$br6: 6px; +$fs12: 0.75rem; +$fs14: 0.875rem; +$fs16: 1rem; +$fs18: 1.125rem; +$fs22: 1.375rem; +$fs24: 1.5rem; +$fs36: 2.25rem; +$fw400: 400; +$fw500: 500; +$fw600: 600; +$fw700: 700; +$lh-088: 0.88; +$lh-115: 1.15; // original $title-lh-sm +$lh-500: 5; // original $title-lh-sm +$size-1: 0.25rem; +$size-2: 0.5rem; +$size-4: 1rem; +$size-5: 1.5rem; +$size-6: 2rem; + +.form-container, +.generic-form { + display: flex; + justify-content: center; + flex-direction: column; + + .forms-container { + display: flex; + margin-top: 40px; + width: 536px; + justify-content: center; + } + + form { + display: flex; + flex-direction: column; + // flex-basis: 368px; + } + + .fields-row { + margin-bottom: 20px; + flex-direction: column; + + .options { + display: flex; + justify-content: flex-end; + font-size: $fs14; + margin-top: 13px; + } + } + + .field { + margin-bottom: 20px; + } + + h1 { + font-size: $fs36; + color: #2c233e; + margin-bottom: 20px; + } + + .subtitle { + font-size: $fs24; + color: #2c233e; + margin-bottom: 20px; + } + + .notification-icon { + justify-content: center; + display: flex; + margin-bottom: 3rem; + + svg { + fill: $color-gray-60; + height: 40%; + width: 40%; + } + } + + .notification-text { + font-size: $fs18; + color: $color-gray-60; + margin-bottom: 20px; + } + + .notification-text-email { + background: $color-gray-10; + border-radius: $br3; + color: $color-gray-60; + font-size: $fs18; + font-weight: $fw500; + margin: 1.5rem 0 2.5rem 0; + padding: 1rem; + text-align: center; + } + + h2 { + font-size: $fs24; + color: $color-gray-60; + // height: 40px; + display: flex; + align-items: center; + } + + a { + &:hover { + text-decoration: underline; + } + } + + p { + color: $color-gray-60; + } + + hr { + border-color: $color-gray-20; + } +} + +.dashboard-header { + display: flex; + align-items: center; + justify-content: space-between; + background-color: $color-white; + height: 63px; + padding: $size-1 $size-4 $size-1 $size-2; + position: relative; + z-index: 10; + user-select: none; + &.team { + display: grid; + grid-template-columns: 20% 1fr 20%; + } + + .element-name { + margin-right: $size-2; + } + + .btn-secondary { + flex-shrink: 0; + z-index: 10; + height: 32px; + svg { + height: 16px; + width: 16px; + } + } + + svg { + fill: $color-black; + height: 14px; + margin-right: $size-1; + width: 14px; + } + + nav { + display: flex; + align-items: flex-end; + justify-content: center; + z-index: 1; + + ul { + display: flex; + font-size: $fs14; + justify-content: center; + margin: 0; + } + + li { + a { + display: flex; + align-items: center; + flex-basis: 140px; + border-bottom: 3px solid transparent; + color: $color-gray-30; + height: 40px; + padding: $size-1 $size-5; + font-weight: $fw400; + &:hover { + color: $color-black; + text-decoration: none; + } + } + + &.active { + a { + color: $color-black; + border-color: $color-primary; + } + } + } + } + + .dashboard-title { + display: flex; + align-items: center; + margin-left: 13px; + + h1 { + color: $color-black; + display: flex; + flex-shrink: 0; + font-size: $fs22; + font-weight: $fw600; + z-index: 10; + user-select: all; + } + + .context-menu.is-open { + margin-top: 10px; + } + } + + .icon { + display: flex; + align-items: center; + cursor: pointer; + margin-left: $size-2; + z-index: 10; + + svg { + fill: $color-gray-40; + width: 15px; + height: 15px; + + &:hover { + fill: $color-primary-dark; + } + } + } + + .dashboard-buttons { + display: flex; + justify-content: flex-end; + align-items: center; + } + + .dashboard-header-actions { + display: flex; + } + + .pin-icon { + margin: 0 $size-2 0 $size-5; + background-color: transparent; + border: none; + svg { + fill: $color-gray-20; + } + + &.active { + svg { + fill: $color-gray-50; + } + } + } +} + +.dashboard-settings { + display: flex; + width: 100%; + justify-content: center; + align-items: center; + + .form-container { + margin-top: 50px; + display: flex; + max-width: 368px; + margin-bottom: 2rem; + width: 100%; + + &.two-columns { + max-width: 536px; + justify-content: space-between; + flex-direction: row; + } + + h2 { + margin-bottom: 1rem; + } + } + + .avatar-form { + display: flex; + flex-direction: column; + width: 120px; + min-width: 120px; + + img { + border-radius: 50%; + flex-shrink: 0; + height: 120px; + margin-right: $size-4; + width: 120px; + } + + .image-change-field { + position: relative; + width: 120px; + height: 120px; + + .update-overlay { + opacity: 0; + cursor: pointer; + position: absolute; + width: 121px; + height: 121px; + border-radius: 50%; + font-size: $fs24; + color: $color-white; + line-height: $lh-500; // Original value was 120px; 120px/24px = 500% => $lh-500 + text-align: center; + background: $color-primary-dark; + z-index: 14; + } + + input[type="file"] { + width: 120px; + height: 120px; + position: absolute; + opacity: 0; + cursor: pointer; + top: 0; + z-index: 15; + } + + &:hover { + .update-overlay { + opacity: 0.8; + } + } + } + } + + .profile-form { + display: flex; + flex-direction: column; + max-width: 368px; + width: 100%; + + .newsletter-subs { + border-bottom: 1px solid $color-gray-20; + border-top: 1px solid $color-gray-20; + padding: 30px 0; + margin-bottom: 31px; + + .newsletter-title { + font-family: "worksans", sans-serif; + color: $color-gray-30; + font-size: $fs14; + } + + label { + font-family: "worksans", sans-serif; + color: $color-gray-60; + font-size: $fs12; + margin-right: -17px; + margin-bottom: 13px; + } + + .info { + font-family: "worksans", sans-serif; + color: $color-gray-30; + font-size: $fs12; + margin-bottom: 8px; + } + + .input-checkbox label { + align-items: flex-start; + } + } + } + + .options-form, + .password-form { + h2 { + font-size: $fs14; + margin-bottom: 20px; + } + } +} + +.access-tokens-modal { + .action-buttons { + gap: 10px; + + .cancel-button { + border: 1px solid $color-gray-30; + background: $color-canvas; + border-radius: $br3; + padding: 0.5rem 1rem; + cursor: pointer; + margin-right: 8px; + + &:hover { + background: $color-gray-20; + } + } + } + .access-token-created { + position: relative; + word-break: break-all; + + .custom-input input { + background-color: $color-success-lighter; + border: 0; + padding: 0 0 0 15px; + } + } + + .help-icon { + border: none; + height: 40px; + width: 40px; + position: absolute; + top: 0; + right: 0; + cursor: pointer; + background-color: $color-success-lighter; + + svg { + fill: $color-gray-30; + } + + &:hover { + svg { + fill: $color-gray-60; + } + } + } + + .token-created-info { + font-size: $fs12; + color: $color-gray-40; + } +} + +.dashboard-settings { + a { + color: $df-secondary; + } + .form-container { + width: 800px; + margin: 80px auto auto 120px; + form { + width: 468px; + .fields-row { + .custom-input, + .custom-select { + flex-direction: column-reverse; + label { + position: relative; + text-transform: uppercase; + color: $df-primary; + font-size: 11px; + margin-bottom: 12px; + margin-left: -4px; + } + input, + select { + background-color: $db-tertiary; + border-radius: 8px; + border-color: transparent; + color: $df-primary; + padding: 0 15px; + &:focus { + outline: 1px solid $da-primary; + } + ::placeholder { + color: $df-secondary; + } + } + .help-icon { + bottom: 12px; + top: auto; + svg { + fill: $df-secondary; + } + } + &.disabled { + input { + background-color: $db-primary; + border-color: $db-cuaternary; + color: $df-secondary; + } + } + .input-container { + background-color: $db-tertiary; + border-radius: 8px; + border-color: transparent; + margin-top: 22px; + .main-content { + label { + position: absolute; + top: -24px; + } + span { + color: $df-primary; + } + } + &:focus { + border: 1px solid $da-primary; + } + } + textarea { + border-radius: 8px; + padding: 12px 14px; + background-color: $db-tertiary; + color: $df-primary; + border: none; + &:focus { + outline: 1px solid $da-primary; + } + } + } + } + .field-title { + color: $df-primary; + } + .field-title:not(:first-child) { + margin-top: 64px; + } + + .field-text { + color: $df-secondary; + } + button, + .btn-secondary { + width: 100%; + font-size: 11px; + text-transform: uppercase; + background-color: $db-tertiary; + color: $df-primary; + &:hover { + color: $da-primary; + background-color: $db-cuaternary; + } + } + hr { + display: none; + } + } + .links { + margin-top: 12px; + } + } +} + +.dashboard-table { + display: flex; + flex-direction: column; + align-items: center; + margin-top: 20px; + font-size: $fs16; + + &.team-members { + margin-bottom: 52px; + } + + &.invitations { + .table-row { + display: grid; + grid-template-columns: 43% 1fr 109px 12px; + } + } + + .table-header { + display: grid; + grid-template-columns: 43% 1fr 109px 12px; + max-width: 1040px; + background-color: $color-white; + color: $color-gray-30; + width: 100%; + height: 40px; + padding: 0px 16px; + } + + .table-rows { + display: flex; + flex-direction: column; + max-width: 1040px; + width: 100%; + margin-top: 16px; + color: $color-black; + } + + .table-row { + display: flex; + width: 100%; + height: 45px; + align-items: center; + padding: 0px 16px; + } + + .table-field { + display: flex; + align-items: center; + + .icon { + padding-left: 10px; + cursor: pointer; + } + } + + svg { + width: 10px; + height: 10px; + fill: $df-primary; + } +} + +.dashboard-table { + .table-header { + background-color: transparent; + color: $df-secondary; + font-size: 12px; + text-transform: uppercase; + } + .table-rows { + .table-row { + background-color: $db-tertiary; + border-radius: 8px; + color: $df-primary; + .rol-selector { + background-color: $db-cuaternary; + border-color: transparent; + border-radius: 8px; + } + } + } + .member-info { + .member-name .you, + .member-email { + color: $df-secondary; + } + } + .status-badge { + border-radius: 8px; + color: $db-primary; + text-transform: uppercase; + } + .empty-invitations { + border: 1px solid $db-cuaternary; + border-radius: 8px; + color: $df-secondary; + } +} + +.dashboard-access-tokens { + width: 800px; + margin-left: 120px; + margin-top: 80px; + .access-tokens-hero-container { + background-color: transparent; + .access-tokens-hero { + width: 468px; + flex-direction: column; + gap: 32px; + background-color: transparent; + margin: 0; + padding: 0; + .desc { + background-color: transparent; + width: 100%; + h2 { + color: $df-primary; + font-size: 24px; + font-weight: regular; + margin-bottom: 32px; + } + p { + color: $df-secondary; + margin-bottom: 0; + font-size: 14px; + } + } + button { + width: 100%; + font-size: 11px; + text-transform: uppercase; + background-color: $db-tertiary; + color: $df-primary; + &:hover { + color: $da-primary; + background-color: $db-cuaternary; + } + } + } + } + .dashboard-table { + width: 800px; + .table-rows { + padding-top: 0; + .table-row { + font-size: 14px; + min-height: 40px; + height: fit-content; + .name { + color: $df-primary; + max-width: 480px; + overflow: hidden; + text-overflow: ellipsis; + display: -webkit-box; + -webkit-line-clamp: 2; + -webkit-box-orient: vertical; + } + .expiration-date { + color: $df-secondary; + } + } + } + } + .access-tokens-empty { + width: 468px; + border: 1px solid $db-cuaternary; + border-radius: 8px; + margin-top: 32px; + font-size: 14px; + background-color: transparent; + color: $df-secondary; + } +} + +.dashboard-access-tokens { + display: flex; + flex-direction: column; + align-items: center; + + .access-tokens-hero-container { + max-width: 1000px; + width: 100%; + display: flex; + flex-direction: column; + } + + .access-tokens-hero { + font-size: $fs14; + padding: $size-6; + background-color: $color-white; + margin-top: $size-6; + display: flex; + justify-content: space-between; + + .desc { + width: 80%; + color: $color-gray-40; + h2 { + margin-bottom: $size-4; + color: $color-black; + } + p { + font-size: $fs16; + } + } + + .btn-primary { + flex-shrink: 0; + } + } + + .access-tokens-empty { + text-align: center; + max-width: 1000px; + width: 100%; + padding: $size-6; + display: flex; + flex-direction: column; + justify-content: center; + align-items: center; + border: 1px dashed $color-gray-20; + color: $color-gray-40; + margin-top: 12px; + min-height: 136px; + } + + .table-row { + background-color: $color-white; + display: grid; + grid-template-columns: 1fr 43% 12px; + height: 63px; + &:not(:first-child) { + margin-top: 8px; + } + } + + .table-field { + &.name { + color: $color-gray-60; + } + + &.expiration-date { + color: $color-gray-40; + font-size: $fs14; + .content { + padding: 2px 5px; + &.expired { + background-color: $color-warning-lighter; + border-radius: $br4; + color: $color-gray-40; + } + } + } + + &.access-token-created { + word-break: break-all; + } + + &.actions { + position: relative; + } + } +} + +.btn-primary { + background-color: $da-tertiary; + border-radius: 8px; + color: $db-primary; + height: 32px; + text-transform: uppercase; + + appearance: none; + align-items: center; + border: none; + cursor: pointer; + display: flex; + font-family: "worksans", sans-serif; + font-size: $fs12; + justify-content: center; + min-width: 25px; + padding: 0 1rem; + transition: all 0.4s; + text-decoration: none; + + &:hover { + background-color: darken($da-tertiary, 10%); + color: $db-primary; + } +} diff --git a/frontend/src/app/main/ui/settings/feedback.cljs b/frontend/src/app/main/ui/settings/feedback.cljs index b5bd3983b4..711537fe30 100644 --- a/frontend/src/app/main/ui/settings/feedback.cljs +++ b/frontend/src/app/main/ui/settings/feedback.cljs @@ -6,6 +6,7 @@ (ns app.main.ui.settings.feedback "Feedback form." + (:require-macros [app.main.style :as stl]) (:require [app.common.spec :as us] [app.main.data.messages :as dm] @@ -13,6 +14,7 @@ [app.main.repo :as rp] [app.main.store :as st] [app.main.ui.components.forms :as fm] + [app.main.ui.context :as ctx] [app.util.dom :as dom] [app.util.i18n :as i18n :refer [tr]] [beicon.core :as rx] @@ -27,7 +29,8 @@ (mf/defc feedback-form [] - (let [profile (mf/deref refs/profile) + (let [new-css-system (mf/use-ctx ctx/new-css-system) + profile (mf/deref refs/profile) form (fm/use-form :spec ::feedback-form :validators [(fm/validate-length :subject fm/max-length-allowed (tr "auth.name.too-long")) (fm/validate-not-empty :subject (tr "auth.name.not-all-space"))]) @@ -59,49 +62,101 @@ (->> (rp/cmd! :send-user-feedback data) (rx/subs on-succes on-error)))))] - [:& fm/form {:class "feedback-form" - :on-submit on-submit - :form form} + (if new-css-system + [:& fm/form {:class "feedback-form" + :on-submit on-submit + :form form} - ;; --- Feedback section - [:h2.field-title (tr "feedback.title")] - [:p.field-text (tr "feedback.subtitle")] + ;; --- Feedback section + [:h2 {:class (stl/css :field-title)} (tr "feedback.title")] + [:p {:class (stl/css :field-text)} (tr "feedback.subtitle")] - [:div.fields-row - [:& fm/input {:label (tr "feedback.subject") - :name :subject}]] - [:div.fields-row - [:& fm/textarea - {:label (tr "feedback.description") - :name :content - :rows 5}]] + [:div {:class (stl/css :fields-row)} + [:& fm/input {:label (tr "feedback.subject") + :name :subject}]] + [:div {:class (stl/css :fields-row :description)} + [:& fm/textarea + {:label (tr "feedback.description") + :name :content + :rows 5}]] - [:> fm/submit-button* - {:label (if @loading (tr "labels.sending") (tr "labels.send")) - :disabled @loading}] + [:> fm/submit-button* + {:label (if @loading (tr "labels.sending") (tr "labels.send")) + :disabled @loading}] - [:hr] + [:hr] - [:h2.field-title (tr "feedback.discourse-title")] - [:p.field-text (tr "feedback.discourse-subtitle1")] + [:h2 {:class (stl/css :field-title)} (tr "feedback.discourse-title")] + [:p {:class (stl/css :field-text)} (tr "feedback.discourse-subtitle1")] - [:a.btn-secondary.btn-large - {:href "https://community.penpot.app" :target "_blank"} - (tr "feedback.discourse-go-to")] - [:hr] + [:a + {:class (stl/css :btn-secondary :btn-large) + :href "https://community.penpot.app" + :target "_blank"} + (tr "feedback.discourse-go-to")] + [:hr] - [:h2.field-title (tr "feedback.twitter-title")] - [:p.field-text (tr "feedback.twitter-subtitle1")] + [:h2 {:class (stl/css :field-title)} (tr "feedback.twitter-title")] + [:p {:class (stl/css :field-text)} (tr "feedback.twitter-subtitle1")] - [:a.btn-secondary.btn-large - {:href "https://twitter.com/penpotapp" :target "_blank"} - (tr "feedback.twitter-go-to")]])) + [:a + {:class (stl/css :btn-secondary :btn-large) + :href "https://twitter.com/penpotapp" + :target "_blank"} + (tr "feedback.twitter-go-to")]] + + ;; OLD + [:& fm/form {:class "feedback-form" + :on-submit on-submit + :form form} + + ;; --- Feedback section + [:h2.field-title (tr "feedback.title")] + [:p.field-text (tr "feedback.subtitle")] + + [:div.fields-row + [:& fm/input {:label (tr "feedback.subject") + :name :subject}]] + [:div.fields-row + [:& fm/textarea + {:label (tr "feedback.description") + :name :content + :rows 5}]] + + [:> fm/submit-button* + {:label (if @loading (tr "labels.sending") (tr "labels.send")) + :disabled @loading}] + + [:hr] + + [:h2.field-title (tr "feedback.discourse-title")] + [:p.field-text (tr "feedback.discourse-subtitle1")] + + [:a.btn-secondary.btn-large + {:href "https://community.penpot.app" :target "_blank"} + (tr "feedback.discourse-go-to")] + [:hr] + + [:h2.field-title (tr "feedback.twitter-title")] + [:p.field-text (tr "feedback.twitter-subtitle1")] + + [:a.btn-secondary.btn-large + {:href "https://twitter.com/penpotapp" :target "_blank"} + (tr "feedback.twitter-go-to")]]))) (mf/defc feedback-page [] - (mf/use-effect - #(dom/set-html-title (tr "title.settings.feedback"))) + (let [new-css-system (mf/use-ctx ctx/new-css-system)] + (mf/use-effect + #(dom/set-html-title (tr "title.settings.feedback"))) + + (if new-css-system + [:div {:class (stl/css :dashboard-settings)} + [:div {:class (stl/css :form-container)} + [:& feedback-form]]] + + ;; OLD + [:div.dashboard-settings + [:div.form-container + [:& feedback-form]]]))) - [:div.dashboard-settings - [:div.form-container - [:& feedback-form]]]) diff --git a/frontend/src/app/main/ui/settings/feedback.scss b/frontend/src/app/main/ui/settings/feedback.scss new file mode 100644 index 0000000000..bc73d1e2fc --- /dev/null +++ b/frontend/src/app/main/ui/settings/feedback.scss @@ -0,0 +1,690 @@ +@import "common/dependencies/colors"; + +$br2: 2px; +$br3: 3px; +$br4: 4px; +$br8: 8px; +$br6: 6px; +$fs12: 0.75rem; +$fs14: 0.875rem; +$fs16: 1rem; +$fs18: 1.125rem; +$fs22: 1.375rem; +$fs24: 1.5rem; +$fs36: 2.25rem; +$fw400: 400; +$fw500: 500; +$fw600: 600; +$fw700: 700; +$lh-088: 0.88; +$lh-115: 1.15; // original $title-lh-sm +$lh-500: 5; // original $title-lh-sm +$size-1: 0.25rem; +$size-2: 0.5rem; +$size-4: 1rem; +$size-5: 1.5rem; +$size-6: 2rem; + +.form-container, +.generic-form { + display: flex; + justify-content: center; + flex-direction: column; + + .forms-container { + display: flex; + margin-top: 40px; + width: 536px; + justify-content: center; + } + + form { + display: flex; + flex-direction: column; + // flex-basis: 368px; + } + + .fields-row { + margin-bottom: 20px; + flex-direction: column; + + .options { + display: flex; + justify-content: flex-end; + font-size: $fs14; + margin-top: 13px; + } + } + + .field { + margin-bottom: 20px; + } + + h1 { + font-size: $fs36; + color: #2c233e; + margin-bottom: 20px; + } + + .subtitle { + font-size: $fs24; + color: #2c233e; + margin-bottom: 20px; + } + + .notification-icon { + justify-content: center; + display: flex; + margin-bottom: 3rem; + + svg { + fill: $color-gray-60; + height: 40%; + width: 40%; + } + } + + .notification-text { + font-size: $fs18; + color: $color-gray-60; + margin-bottom: 20px; + } + + .notification-text-email { + background: $color-gray-10; + border-radius: $br3; + color: $color-gray-60; + font-size: $fs18; + font-weight: $fw500; + margin: 1.5rem 0 2.5rem 0; + padding: 1rem; + text-align: center; + } + + h2 { + font-size: $fs24; + color: $color-gray-60; + // height: 40px; + display: flex; + align-items: center; + } + + a { + &:hover { + text-decoration: underline; + } + } + + p { + color: $color-gray-60; + } + + hr { + border-color: $color-gray-20; + } +} + +.dashboard-header { + display: flex; + align-items: center; + justify-content: space-between; + background-color: $color-white; + height: 63px; + padding: $size-1 $size-4 $size-1 $size-2; + position: relative; + z-index: 10; + user-select: none; + &.team { + display: grid; + grid-template-columns: 20% 1fr 20%; + } + + .element-name { + margin-right: $size-2; + } + + .btn-secondary { + flex-shrink: 0; + z-index: 10; + height: 32px; + svg { + height: 16px; + width: 16px; + } + } + + svg { + fill: $color-black; + height: 14px; + margin-right: $size-1; + width: 14px; + } + + nav { + display: flex; + align-items: flex-end; + justify-content: center; + z-index: 1; + + ul { + display: flex; + font-size: $fs14; + justify-content: center; + margin: 0; + } + + li { + a { + display: flex; + align-items: center; + flex-basis: 140px; + border-bottom: 3px solid transparent; + color: $color-gray-30; + height: 40px; + padding: $size-1 $size-5; + font-weight: $fw400; + &:hover { + color: $color-black; + text-decoration: none; + } + } + + &.active { + a { + color: $color-black; + border-color: $color-primary; + } + } + } + } + + .dashboard-title { + display: flex; + align-items: center; + margin-left: 13px; + + h1 { + color: $color-black; + display: flex; + flex-shrink: 0; + font-size: $fs22; + font-weight: $fw600; + z-index: 10; + user-select: all; + } + + .context-menu.is-open { + margin-top: 10px; + } + } + + .icon { + display: flex; + align-items: center; + cursor: pointer; + margin-left: $size-2; + z-index: 10; + + svg { + fill: $color-gray-40; + width: 15px; + height: 15px; + + &:hover { + fill: $color-primary-dark; + } + } + } + + .dashboard-buttons { + display: flex; + justify-content: flex-end; + align-items: center; + } + + .dashboard-header-actions { + display: flex; + } + + .pin-icon { + margin: 0 $size-2 0 $size-5; + background-color: transparent; + border: none; + svg { + fill: $color-gray-20; + } + + &.active { + svg { + fill: $color-gray-50; + } + } + } +} + +.dashboard-settings { + display: flex; + width: 100%; + justify-content: center; + align-items: center; + + .form-container { + margin-top: 50px; + display: flex; + max-width: 368px; + margin-bottom: 2rem; + width: 100%; + + &.two-columns { + max-width: 536px; + justify-content: space-between; + flex-direction: row; + } + + h2 { + margin-bottom: 1rem; + } + } + + .avatar-form { + display: flex; + flex-direction: column; + width: 120px; + min-width: 120px; + + img { + border-radius: 50%; + flex-shrink: 0; + height: 120px; + margin-right: $size-4; + width: 120px; + } + + .image-change-field { + position: relative; + width: 120px; + height: 120px; + + .update-overlay { + opacity: 0; + cursor: pointer; + position: absolute; + width: 121px; + height: 121px; + border-radius: 50%; + font-size: $fs24; + color: $color-white; + line-height: $lh-500; // Original value was 120px; 120px/24px = 500% => $lh-500 + text-align: center; + background: $color-primary-dark; + z-index: 14; + } + + input[type="file"] { + width: 120px; + height: 120px; + position: absolute; + opacity: 0; + cursor: pointer; + top: 0; + z-index: 15; + } + + &:hover { + .update-overlay { + opacity: 0.8; + } + } + } + } + + .profile-form { + display: flex; + flex-direction: column; + max-width: 368px; + width: 100%; + + .newsletter-subs { + border-bottom: 1px solid $color-gray-20; + border-top: 1px solid $color-gray-20; + padding: 30px 0; + margin-bottom: 31px; + + .newsletter-title { + font-family: "worksans", sans-serif; + color: $color-gray-30; + font-size: $fs14; + } + + label { + font-family: "worksans", sans-serif; + color: $color-gray-60; + font-size: $fs12; + margin-right: -17px; + margin-bottom: 13px; + } + + .info { + font-family: "worksans", sans-serif; + color: $color-gray-30; + font-size: $fs12; + margin-bottom: 8px; + } + + .input-checkbox label { + align-items: flex-start; + } + } + } + + .options-form, + .password-form { + h2 { + font-size: $fs14; + margin-bottom: 20px; + } + } +} + +.dashboard-access-tokens { + display: flex; + flex-direction: column; + align-items: center; + + .access-tokens-hero-container { + max-width: 1000px; + width: 100%; + display: flex; + flex-direction: column; + } + + .access-tokens-hero { + font-size: $fs14; + padding: $size-6; + background-color: $color-white; + margin-top: $size-6; + display: flex; + justify-content: space-between; + + .desc { + width: 80%; + color: $color-gray-40; + h2 { + margin-bottom: $size-4; + color: $color-black; + } + p { + font-size: $fs16; + } + } + + .btn-primary { + flex-shrink: 0; + } + } + + .access-tokens-empty { + text-align: center; + max-width: 1000px; + width: 100%; + padding: $size-6; + display: flex; + flex-direction: column; + justify-content: center; + align-items: center; + border: 1px dashed $color-gray-20; + color: $color-gray-40; + margin-top: 12px; + min-height: 136px; + } + + .table-row { + background-color: $color-white; + display: grid; + grid-template-columns: 1fr 43% 12px; + height: 63px; + &:not(:first-child) { + margin-top: 8px; + } + } + + .table-field { + &.name { + color: $color-gray-60; + } + + &.expiration-date { + color: $color-gray-40; + font-size: $fs14; + .content { + padding: 2px 5px; + &.expired { + background-color: $color-warning-lighter; + border-radius: $br4; + color: $color-gray-40; + } + } + } + + &.access-token-created { + word-break: break-all; + } + + &.actions { + position: relative; + } + } +} + +.access-tokens-modal { + .action-buttons { + gap: 10px; + + .cancel-button { + border: 1px solid $color-gray-30; + background: $color-canvas; + border-radius: $br3; + padding: 0.5rem 1rem; + cursor: pointer; + margin-right: 8px; + + &:hover { + background: $color-gray-20; + } + } + } + .access-token-created { + position: relative; + word-break: break-all; + + .custom-input input { + background-color: $color-success-lighter; + border: 0; + padding: 0 0 0 15px; + } + } + + .help-icon { + border: none; + height: 40px; + width: 40px; + position: absolute; + top: 0; + right: 0; + cursor: pointer; + background-color: $color-success-lighter; + + svg { + fill: $color-gray-30; + } + + &:hover { + svg { + fill: $color-gray-60; + } + } + } + + .token-created-info { + font-size: $fs12; + color: $color-gray-40; + } +} + +.dashboard-settings { + a { + color: $df-secondary; + } + .form-container { + width: 800px; + margin: 80px auto auto 120px; + form { + width: 468px; + .fields-row { + .custom-input, + .custom-select { + flex-direction: column-reverse; + label { + position: relative; + text-transform: uppercase; + color: $df-primary; + font-size: 11px; + margin-bottom: 12px; + margin-left: -4px; + } + input, + select { + background-color: $db-tertiary; + border-radius: 8px; + border-color: transparent; + color: $df-primary; + padding: 0 15px; + &:focus { + outline: 1px solid $da-primary; + } + ::placeholder { + color: $df-secondary; + } + } + .help-icon { + bottom: 12px; + top: auto; + svg { + fill: $df-secondary; + } + } + &.disabled { + input { + background-color: $db-primary; + border-color: $db-cuaternary; + color: $df-secondary; + } + } + .input-container { + background-color: $db-tertiary; + border-radius: 8px; + border-color: transparent; + margin-top: 22px; + .main-content { + label { + position: absolute; + top: -24px; + } + span { + color: $df-primary; + } + } + &:focus { + border: 1px solid $da-primary; + } + } + textarea { + border-radius: 8px; + padding: 12px 14px; + background-color: $db-tertiary; + color: $df-primary; + border: none; + &:focus { + outline: 1px solid $da-primary; + } + } + } + } + .field-title { + color: $df-primary; + } + .field-title:not(:first-child) { + margin-top: 64px; + } + + .field-text { + color: $df-secondary; + } + button, + .btn-secondary { + width: 100%; + font-size: 11px; + text-transform: uppercase; + background-color: $db-tertiary; + color: $df-primary; + &:hover { + color: $da-primary; + background-color: $db-cuaternary; + } + } + hr { + display: none; + } + } + .links { + margin-top: 12px; + } + } +} + +.btn-secondary { + background-color: $db-tertiary; + text-transform: uppercase; + border: none; + color: $df-primary; + border-radius: 8px; + + font-size: 0.75rem; + padding: 0 1rem; + cursor: pointer; + display: flex; + justify-content: center; + align-items: center; + height: 40px; + + &:hover { + background-color: $db-cuaternary; + color: $da-primary; + svg { + fill: $da-primary; + } + } +} + +.description { + :global(.custom-input label) { + position: initial; + margin-bottom: 8px; + } + + :global(.custom-input textarea) { + background-color: $color-white; + background-color: $db-tertiary; + border-radius: 8px; + border: none; + color: $df-primary; + font-size: $fs14; + margin: 0; + padding: 15px 15px 0 15px; + width: 100%; + + &:focus { + outline: 1px solid $da-primary; + } + } +} diff --git a/frontend/src/app/main/ui/settings/options.cljs b/frontend/src/app/main/ui/settings/options.cljs index 3d3424a024..78a0c5130a 100644 --- a/frontend/src/app/main/ui/settings/options.cljs +++ b/frontend/src/app/main/ui/settings/options.cljs @@ -5,14 +5,15 @@ ;; Copyright (c) KALEIDOS INC (ns app.main.ui.settings.options + (:require-macros [app.main.style :as stl]) (:require [app.common.spec :as us] [app.main.data.messages :as dm] [app.main.data.users :as du] - [app.main.features :as features] [app.main.refs :as refs] [app.main.store :as st] [app.main.ui.components.forms :as fm] + [app.main.ui.context :as ctx] [app.util.dom :as dom] [app.util.i18n :as i18n :refer [tr]] [cljs.spec.alpha :as s] @@ -37,48 +38,78 @@ (mf/defc options-form {::mf/wrap-props false} [] - (let [profile (mf/deref refs/profile) + (let [new-css-system (mf/use-ctx ctx/new-css-system) + profile (mf/deref refs/profile) initial (mf/with-memo [profile] (update profile :lang #(or % ""))) form (fm/use-form :spec ::options-form - :initial initial) - new-css-system (features/use-feature "styles/v2")] + :initial initial)] - [:& fm/form {:class "options-form" - :on-submit on-submit - :form form} + (if new-css-system + [:& fm/form {:class (stl/css :options-form) + :on-submit on-submit + :form form} - [:h2 (tr "labels.language")] + [:h2 (tr "labels.language")] - [:div.fields-row - [:& fm/select {:options (into [{:label "Auto (browser)" :value ""}] - i18n/supported-locales) - :label (tr "dashboard.select-ui-language") - :default "" - :name :lang - :data-test "setting-lang"}]] + [:div {:class (stl/css :fields-row)} + [:& fm/select {:options (into [{:label "Auto (browser)" :value ""}] + i18n/supported-locales) + :label (tr "dashboard.select-ui-language") + :default "" + :name :lang + :data-test "setting-lang"}]] - (when new-css-system [:h2 (tr "dashboard.theme-change")] - [:div.fields-row + [:div {:class (stl/css :fields-row)} [:& fm/select {:label (tr "dashboard.select-ui-theme") :name :theme :default "default" :options [{:label "Penpot Dark (default)" :value "default"} {:label "Penpot Light" :value "light"}] - :data-test "setting-theme"}]]) - [:> fm/submit-button* - {:label (tr "dashboard.update-settings") - :data-test "submit-lang-change"}]])) + :data-test "setting-theme"}]] + + [:> fm/submit-button* + {:label (tr "dashboard.update-settings") + :data-test "submit-lang-change"}]] + + ;; OLD + [:& fm/form {:class "options-form" + :on-submit on-submit + :form form} + + [:h2 (tr "labels.language")] + + [:div.fields-row + [:& fm/select {:options (into [{:label "Auto (browser)" :value ""}] + i18n/supported-locales) + :label (tr "dashboard.select-ui-language") + :default "" + :name :lang + :data-test "setting-lang"}]] + + [:> fm/submit-button* + {:label (tr "dashboard.update-settings") + :data-test "submit-lang-change"}]]))) ;; --- Password Page (mf/defc options-page [] - (mf/use-effect - #(dom/set-html-title (tr "title.settings.options"))) + (let [new-css-system (mf/use-ctx ctx/new-css-system)] + (mf/use-effect + #(dom/set-html-title (tr "title.settings.options"))) + + (if new-css-system + [:div {:class (stl/css :dashboard-settings)} + [:div + {:class (stl/css :form-container) + :data-test "settings-form"} + [:& options-form {}]]] + + ;; OLD + [:div.dashboard-settings + [:div.form-container + {:data-test "settings-form"} + [:& options-form {}]]]))) - [:div.dashboard-settings - [:div.form-container - {:data-test "settings-form"} - [:& options-form {}]]]) diff --git a/frontend/src/app/main/ui/settings/options.scss b/frontend/src/app/main/ui/settings/options.scss new file mode 100644 index 0000000000..0f94e82b4f --- /dev/null +++ b/frontend/src/app/main/ui/settings/options.scss @@ -0,0 +1,642 @@ +@import "common/dependencies/colors"; + +$br3: 3px; +$br4: 4px; +$br8: 8px; +$br6: 6px; +$fs12: 0.75rem; +$fs14: 0.875rem; +$fs16: 1rem; +$fs18: 1.125rem; +$fs22: 1.375rem; +$fs24: 1.5rem; +$fs36: 2.25rem; +$fw400: 400; +$fw500: 500; +$fw600: 600; +$fw700: 700; +$lh-088: 0.88; +$lh-115: 1.15; // original $title-lh-sm +$lh-500: 5; // original $title-lh-sm +$size-1: 0.25rem; +$size-2: 0.5rem; +$size-4: 1rem; +$size-5: 1.5rem; +$size-6: 2rem; + +.form-container, +.generic-form { + display: flex; + justify-content: center; + flex-direction: column; + + .forms-container { + display: flex; + margin-top: 40px; + width: 536px; + justify-content: center; + } + + form { + display: flex; + flex-direction: column; + // flex-basis: 368px; + } + + .fields-row { + margin-bottom: 20px; + flex-direction: column; + + .options { + display: flex; + justify-content: flex-end; + font-size: $fs14; + margin-top: 13px; + } + } + + .field { + margin-bottom: 20px; + } + + h1 { + font-size: $fs36; + color: #2c233e; + margin-bottom: 20px; + } + + .subtitle { + font-size: $fs24; + color: #2c233e; + margin-bottom: 20px; + } + + .notification-icon { + justify-content: center; + display: flex; + margin-bottom: 3rem; + + svg { + fill: $color-gray-60; + height: 40%; + width: 40%; + } + } + + .notification-text { + font-size: $fs18; + color: $color-gray-60; + margin-bottom: 20px; + } + + .notification-text-email { + background: $color-gray-10; + border-radius: $br3; + color: $color-gray-60; + font-size: $fs18; + font-weight: $fw500; + margin: 1.5rem 0 2.5rem 0; + padding: 1rem; + text-align: center; + } + + h2 { + font-size: $fs24; + color: $df-primary; + // height: 40px; + display: flex; + align-items: center; + } + + a { + &:hover { + text-decoration: underline; + } + } + + p { + color: $color-gray-60; + } + + hr { + border-color: $color-gray-20; + } +} + +.dashboard-header { + display: flex; + align-items: center; + justify-content: space-between; + background-color: $color-white; + height: 63px; + padding: $size-1 $size-4 $size-1 $size-2; + position: relative; + z-index: 10; + user-select: none; + &.team { + display: grid; + grid-template-columns: 20% 1fr 20%; + } + + .element-name { + margin-right: $size-2; + } + + .btn-secondary { + flex-shrink: 0; + z-index: 10; + height: 32px; + svg { + height: 16px; + width: 16px; + } + } + + svg { + fill: $color-black; + height: 14px; + margin-right: $size-1; + width: 14px; + } + + nav { + display: flex; + align-items: flex-end; + justify-content: center; + z-index: 1; + + ul { + display: flex; + font-size: $fs14; + justify-content: center; + margin: 0; + } + + li { + a { + display: flex; + align-items: center; + flex-basis: 140px; + border-bottom: 3px solid transparent; + color: $color-gray-30; + height: 40px; + padding: $size-1 $size-5; + font-weight: $fw400; + &:hover { + color: $color-black; + text-decoration: none; + } + } + + &.active { + a { + color: $color-black; + border-color: $color-primary; + } + } + } + } + + .dashboard-title { + display: flex; + align-items: center; + margin-left: 13px; + + h1 { + color: $color-black; + display: flex; + flex-shrink: 0; + font-size: $fs22; + font-weight: $fw600; + z-index: 10; + user-select: all; + } + + .context-menu.is-open { + margin-top: 10px; + } + } + + .icon { + display: flex; + align-items: center; + cursor: pointer; + margin-left: $size-2; + z-index: 10; + + svg { + fill: $color-gray-40; + width: 15px; + height: 15px; + + &:hover { + fill: $color-primary-dark; + } + } + } + + .dashboard-buttons { + display: flex; + justify-content: flex-end; + align-items: center; + } + + .dashboard-header-actions { + display: flex; + } + + .pin-icon { + margin: 0 $size-2 0 $size-5; + background-color: transparent; + border: none; + svg { + fill: $color-gray-20; + } + + &.active { + svg { + fill: $color-gray-50; + } + } + } +} + +.dashboard-settings { + display: flex; + width: 100%; + justify-content: center; + align-items: center; + + .form-container { + margin-top: 50px; + display: flex; + max-width: 368px; + margin-bottom: 2rem; + width: 100%; + + &.two-columns { + max-width: 536px; + justify-content: space-between; + flex-direction: row; + } + + h2 { + margin-bottom: 1rem; + } + } + + .avatar-form { + display: flex; + flex-direction: column; + width: 120px; + min-width: 120px; + + img { + border-radius: 50%; + flex-shrink: 0; + height: 120px; + margin-right: $size-4; + width: 120px; + } + + .image-change-field { + position: relative; + width: 120px; + height: 120px; + + .update-overlay { + opacity: 0; + cursor: pointer; + position: absolute; + width: 121px; + height: 121px; + border-radius: 50%; + font-size: $fs24; + color: $color-white; + line-height: $lh-500; // Original value was 120px; 120px/24px = 500% => $lh-500 + text-align: center; + background: $color-primary-dark; + z-index: 14; + } + + input[type="file"] { + width: 120px; + height: 120px; + position: absolute; + opacity: 0; + cursor: pointer; + top: 0; + z-index: 15; + } + + &:hover { + .update-overlay { + opacity: 0.8; + } + } + } + } + + .profile-form { + display: flex; + flex-direction: column; + max-width: 368px; + width: 100%; + + .newsletter-subs { + border-bottom: 1px solid $color-gray-20; + border-top: 1px solid $color-gray-20; + padding: 30px 0; + margin-bottom: 31px; + + .newsletter-title { + font-family: "worksans", sans-serif; + color: $color-gray-30; + font-size: $fs14; + } + + label { + font-family: "worksans", sans-serif; + color: $color-gray-60; + font-size: $fs12; + margin-right: -17px; + margin-bottom: 13px; + } + + .info { + font-family: "worksans", sans-serif; + color: $color-gray-30; + font-size: $fs12; + margin-bottom: 8px; + } + + .input-checkbox label { + align-items: flex-start; + } + } + } + + .options-form, + .password-form { + h2 { + font-size: $fs14; + margin-bottom: 20px; + } + } +} + +.dashboard-access-tokens { + display: flex; + flex-direction: column; + align-items: center; + + .access-tokens-hero-container { + max-width: 1000px; + width: 100%; + display: flex; + flex-direction: column; + } + + .access-tokens-hero { + font-size: $fs14; + padding: $size-6; + background-color: $color-white; + margin-top: $size-6; + display: flex; + justify-content: space-between; + + .desc { + width: 80%; + color: $color-gray-40; + h2 { + margin-bottom: $size-4; + color: $color-black; + } + p { + font-size: $fs16; + } + } + + .btn-primary { + flex-shrink: 0; + } + } + + .access-tokens-empty { + text-align: center; + max-width: 1000px; + width: 100%; + padding: $size-6; + display: flex; + flex-direction: column; + justify-content: center; + align-items: center; + border: 1px dashed $color-gray-20; + color: $color-gray-40; + margin-top: 12px; + min-height: 136px; + } + + .table-row { + background-color: $color-white; + display: grid; + grid-template-columns: 1fr 43% 12px; + height: 63px; + &:not(:first-child) { + margin-top: 8px; + } + } + + .table-field { + &.name { + color: $color-gray-60; + } + + &.expiration-date { + color: $color-gray-40; + font-size: $fs14; + .content { + padding: 2px 5px; + &.expired { + background-color: $color-warning-lighter; + border-radius: $br4; + color: $color-gray-40; + } + } + } + + &.access-token-created { + word-break: break-all; + } + + &.actions { + position: relative; + } + } +} + +.access-tokens-modal { + .action-buttons { + gap: 10px; + + .cancel-button { + border: 1px solid $color-gray-30; + background: $color-canvas; + border-radius: $br3; + padding: 0.5rem 1rem; + cursor: pointer; + margin-right: 8px; + + &:hover { + background: $color-gray-20; + } + } + } + .access-token-created { + position: relative; + word-break: break-all; + + .custom-input input { + background-color: $color-success-lighter; + border: 0; + padding: 0 0 0 15px; + } + } + + .help-icon { + border: none; + height: 40px; + width: 40px; + position: absolute; + top: 0; + right: 0; + cursor: pointer; + background-color: $color-success-lighter; + + svg { + fill: $color-gray-30; + } + + &:hover { + svg { + fill: $color-gray-60; + } + } + } + + .token-created-info { + font-size: $fs12; + color: $color-gray-40; + } +} + +.dashboard-settings { + a { + color: $df-secondary; + } + .form-container { + width: 800px; + margin: 80px auto auto 120px; + form { + width: 468px; + .fields-row { + .custom-input, + .custom-select { + flex-direction: column-reverse; + label { + position: relative; + text-transform: uppercase; + color: $df-primary; + font-size: 11px; + margin-bottom: 12px; + margin-left: -4px; + } + input, + select { + background-color: $db-tertiary; + border-radius: 8px; + border-color: transparent; + color: $df-primary; + padding: 0 15px; + &:focus { + outline: 1px solid $da-primary; + } + ::placeholder { + color: $df-secondary; + } + } + .help-icon { + bottom: 12px; + top: auto; + svg { + fill: $df-secondary; + } + } + &.disabled { + input { + background-color: $db-primary; + border-color: $db-cuaternary; + color: $df-secondary; + } + } + .input-container { + background-color: $db-tertiary; + border-radius: 8px; + border-color: transparent; + margin-top: 22px; + .main-content { + label { + position: absolute; + top: -24px; + } + span { + color: $df-primary; + } + } + &:focus { + border: 1px solid $da-primary; + } + } + textarea { + border-radius: 8px; + padding: 12px 14px; + background-color: $db-tertiary; + color: $df-primary; + border: none; + &:focus { + outline: 1px solid $da-primary; + } + } + } + } + .field-title { + color: $df-primary; + } + .field-title:not(:first-child) { + margin-top: 64px; + } + + .field-text { + color: $df-secondary; + } + button, + .btn-secondary { + width: 100%; + font-size: 11px; + text-transform: uppercase; + background-color: $db-tertiary; + color: $df-primary; + &:hover { + color: $da-primary; + background-color: $db-cuaternary; + } + } + hr { + display: none; + } + } + .links { + margin-top: 12px; + } + } +} diff --git a/frontend/src/app/main/ui/settings/password.cljs b/frontend/src/app/main/ui/settings/password.cljs index 50f13b1856..27eb69a123 100644 --- a/frontend/src/app/main/ui/settings/password.cljs +++ b/frontend/src/app/main/ui/settings/password.cljs @@ -5,12 +5,14 @@ ;; Copyright (c) KALEIDOS INC (ns app.main.ui.settings.password + (:require-macros [app.main.style :as stl]) (:require [app.common.spec :as us] [app.main.data.messages :as dm] [app.main.data.users :as udu] [app.main.store :as st] [app.main.ui.components.forms :as fm] + [app.main.ui.context :as ctx] [app.util.dom :as dom] [app.util.i18n :as i18n :refer [t tr]] [cljs.spec.alpha :as s] @@ -69,47 +71,85 @@ (mf/defc password-form [{:keys [locale] :as props}] - (let [initial (mf/use-memo (constantly {:password-old nil})) + (let [new-css-system (mf/use-ctx ctx/new-css-system) + initial (mf/use-memo (constantly {:password-old nil})) form (fm/use-form :spec ::password-form :validators [(fm/validate-not-all-spaces :password-old (tr "auth.password-not-empty")) (fm/validate-not-empty :password-1 (tr "auth.password-not-empty")) (fm/validate-not-empty :password-2 (tr "auth.password-not-empty")) password-equality] :initial initial)] - [:& fm/form {:class "password-form" - :on-submit on-submit - :form form} - [:h2 (t locale "dashboard.password-change")] - [:div.fields-row - [:& fm/input - {:type "password" - :name :password-old - :auto-focus? true - :label (t locale "labels.old-password")}]] + (if new-css-system + [:& fm/form {:class (stl/css :password-form) + :on-submit on-submit + :form form} + [:h2 (t locale "dashboard.password-change")] + [:div {:class (stl/css :fields-row)} + [:& fm/input + {:type "password" + :name :password-old + :auto-focus? true + :label (t locale "labels.old-password")}]] - [:div.fields-row - [:& fm/input - {:type "password" - :name :password-1 - :label (t locale "labels.new-password")}]] + [:div {:class (stl/css :fields-row)} + [:& fm/input + {:type "password" + :name :password-1 + :label (t locale "labels.new-password")}]] - [:div.fields-row - [:& fm/input - {:type "password" - :name :password-2 - :label (t locale "labels.confirm-password")}]] + [:div {:class (stl/css :fields-row)} + [:& fm/input + {:type "password" + :name :password-2 + :label (t locale "labels.confirm-password")}]] - [:> fm/submit-button* - {:label (t locale "dashboard.update-settings") - :data-test "submit-password"}]])) + [:> fm/submit-button* + {:label (t locale "dashboard.update-settings") + :data-test "submit-password"}]] + + ;; OLD + [:& fm/form {:class "password-form" + :on-submit on-submit + :form form} + [:h2 (t locale "dashboard.password-change")] + [:div.fields-row + [:& fm/input + {:type "password" + :name :password-old + :auto-focus? true + :label (t locale "labels.old-password")}]] + + [:div.fields-row + [:& fm/input + {:type "password" + :name :password-1 + :label (t locale "labels.new-password")}]] + + [:div.fields-row + [:& fm/input + {:type "password" + :name :password-2 + :label (t locale "labels.confirm-password")}]] + + [:> fm/submit-button* + {:label (t locale "dashboard.update-settings") + :data-test "submit-password"}]]))) ;; --- Password Page (mf/defc password-page [{:keys [locale]}] - (mf/use-effect - #(dom/set-html-title (tr "title.settings.password"))) + (let [new-css-system (mf/use-ctx ctx/new-css-system)] + (mf/use-effect + #(dom/set-html-title (tr "title.settings.password"))) + + (if new-css-system + [:section {:class (stl/css :dashboard-settings :form-container)} + [:div {:class (stl/css :form-container)} + [:& password-form {:locale locale}]]] + + ;; old + [:section.dashboard-settings.form-container + [:div.form-container + [:& password-form {:locale locale}]]]))) - [:section.dashboard-settings.form-container - [:div.form-container - [:& password-form {:locale locale}]]]) diff --git a/frontend/src/app/main/ui/settings/password.scss b/frontend/src/app/main/ui/settings/password.scss new file mode 100644 index 0000000000..aa7e88cbca --- /dev/null +++ b/frontend/src/app/main/ui/settings/password.scss @@ -0,0 +1,642 @@ +@import "common/dependencies/colors"; + +$br3: 3px; +$br4: 4px; +$br8: 8px; +$br6: 6px; +$fs12: 0.75rem; +$fs14: 0.875rem; +$fs16: 1rem; +$fs18: 1.125rem; +$fs22: 1.375rem; +$fs24: 1.5rem; +$fs36: 2.25rem; +$fw400: 400; +$fw500: 500; +$fw600: 600; +$fw700: 700; +$lh-088: 0.88; +$lh-115: 1.15; // original $title-lh-sm +$lh-500: 5; // original $title-lh-sm +$size-1: 0.25rem; +$size-2: 0.5rem; +$size-4: 1rem; +$size-5: 1.5rem; +$size-6: 2rem; + +.form-container, +.generic-form { + display: flex; + justify-content: center; + flex-direction: column; + + .forms-container { + display: flex; + margin-top: 40px; + width: 536px; + justify-content: center; + } + + form { + display: flex; + flex-direction: column; + // flex-basis: 368px; + } + + .fields-row { + margin-bottom: 20px; + flex-direction: column; + + .options { + display: flex; + justify-content: flex-end; + font-size: $fs14; + margin-top: 13px; + } + } + + .field { + margin-bottom: 20px; + } + + h1 { + font-size: $fs36; + color: #2c233e; + margin-bottom: 20px; + } + + .subtitle { + font-size: $fs24; + color: #2c233e; + margin-bottom: 20px; + } + + .notification-icon { + justify-content: center; + display: flex; + margin-bottom: 3rem; + + svg { + fill: $color-gray-60; + height: 40%; + width: 40%; + } + } + + .notification-text { + font-size: $fs18; + color: $color-gray-60; + margin-bottom: 20px; + } + + .notification-text-email { + background: $color-gray-10; + border-radius: $br3; + color: $color-gray-60; + font-size: $fs18; + font-weight: $fw500; + margin: 1.5rem 0 2.5rem 0; + padding: 1rem; + text-align: center; + } + + h2 { + font-size: $fs24; + color: $color-gray-60; + // height: 40px; + display: flex; + align-items: center; + } + + a { + &:hover { + text-decoration: underline; + } + } + + p { + color: $color-gray-60; + } + + hr { + border-color: $color-gray-20; + } +} + +.dashboard-header { + display: flex; + align-items: center; + justify-content: space-between; + background-color: $color-white; + height: 63px; + padding: $size-1 $size-4 $size-1 $size-2; + position: relative; + z-index: 10; + user-select: none; + &.team { + display: grid; + grid-template-columns: 20% 1fr 20%; + } + + .element-name { + margin-right: $size-2; + } + + .btn-secondary { + flex-shrink: 0; + z-index: 10; + height: 32px; + svg { + height: 16px; + width: 16px; + } + } + + svg { + fill: $color-black; + height: 14px; + margin-right: $size-1; + width: 14px; + } + + nav { + display: flex; + align-items: flex-end; + justify-content: center; + z-index: 1; + + ul { + display: flex; + font-size: $fs14; + justify-content: center; + margin: 0; + } + + li { + a { + display: flex; + align-items: center; + flex-basis: 140px; + border-bottom: 3px solid transparent; + color: $color-gray-30; + height: 40px; + padding: $size-1 $size-5; + font-weight: $fw400; + &:hover { + color: $color-black; + text-decoration: none; + } + } + + &.active { + a { + color: $color-black; + border-color: $color-primary; + } + } + } + } + + .dashboard-title { + display: flex; + align-items: center; + margin-left: 13px; + + h1 { + color: $color-black; + display: flex; + flex-shrink: 0; + font-size: $fs22; + font-weight: $fw600; + z-index: 10; + user-select: all; + } + + .context-menu.is-open { + margin-top: 10px; + } + } + + .icon { + display: flex; + align-items: center; + cursor: pointer; + margin-left: $size-2; + z-index: 10; + + svg { + fill: $color-gray-40; + width: 15px; + height: 15px; + + &:hover { + fill: $color-primary-dark; + } + } + } + + .dashboard-buttons { + display: flex; + justify-content: flex-end; + align-items: center; + } + + .dashboard-header-actions { + display: flex; + } + + .pin-icon { + margin: 0 $size-2 0 $size-5; + background-color: transparent; + border: none; + svg { + fill: $color-gray-20; + } + + &.active { + svg { + fill: $color-gray-50; + } + } + } +} + +.dashboard-settings { + display: flex; + width: 100%; + justify-content: center; + align-items: center; + + .form-container { + margin-top: 50px; + display: flex; + max-width: 368px; + margin-bottom: 2rem; + width: 100%; + + &.two-columns { + max-width: 536px; + justify-content: space-between; + flex-direction: row; + } + + h2 { + margin-bottom: 1rem; + } + } + + .avatar-form { + display: flex; + flex-direction: column; + width: 120px; + min-width: 120px; + + img { + border-radius: 50%; + flex-shrink: 0; + height: 120px; + margin-right: $size-4; + width: 120px; + } + + .image-change-field { + position: relative; + width: 120px; + height: 120px; + + .update-overlay { + opacity: 0; + cursor: pointer; + position: absolute; + width: 121px; + height: 121px; + border-radius: 50%; + font-size: $fs24; + color: $color-white; + line-height: $lh-500; // Original value was 120px; 120px/24px = 500% => $lh-500 + text-align: center; + background: $color-primary-dark; + z-index: 14; + } + + input[type="file"] { + width: 120px; + height: 120px; + position: absolute; + opacity: 0; + cursor: pointer; + top: 0; + z-index: 15; + } + + &:hover { + .update-overlay { + opacity: 0.8; + } + } + } + } + + .profile-form { + display: flex; + flex-direction: column; + max-width: 368px; + width: 100%; + + .newsletter-subs { + border-bottom: 1px solid $color-gray-20; + border-top: 1px solid $color-gray-20; + padding: 30px 0; + margin-bottom: 31px; + + .newsletter-title { + font-family: "worksans", sans-serif; + color: $color-gray-30; + font-size: $fs14; + } + + label { + font-family: "worksans", sans-serif; + color: $color-gray-60; + font-size: $fs12; + margin-right: -17px; + margin-bottom: 13px; + } + + .info { + font-family: "worksans", sans-serif; + color: $color-gray-30; + font-size: $fs12; + margin-bottom: 8px; + } + + .input-checkbox label { + align-items: flex-start; + } + } + } + + .options-form, + .password-form { + h2 { + font-size: $fs14; + margin-bottom: 20px; + } + } +} + +.dashboard-access-tokens { + display: flex; + flex-direction: column; + align-items: center; + + .access-tokens-hero-container { + max-width: 1000px; + width: 100%; + display: flex; + flex-direction: column; + } + + .access-tokens-hero { + font-size: $fs14; + padding: $size-6; + background-color: $color-white; + margin-top: $size-6; + display: flex; + justify-content: space-between; + + .desc { + width: 80%; + color: $color-gray-40; + h2 { + margin-bottom: $size-4; + color: $color-black; + } + p { + font-size: $fs16; + } + } + + .btn-primary { + flex-shrink: 0; + } + } + + .access-tokens-empty { + text-align: center; + max-width: 1000px; + width: 100%; + padding: $size-6; + display: flex; + flex-direction: column; + justify-content: center; + align-items: center; + border: 1px dashed $color-gray-20; + color: $color-gray-40; + margin-top: 12px; + min-height: 136px; + } + + .table-row { + background-color: $color-white; + display: grid; + grid-template-columns: 1fr 43% 12px; + height: 63px; + &:not(:first-child) { + margin-top: 8px; + } + } + + .table-field { + &.name { + color: $color-gray-60; + } + + &.expiration-date { + color: $color-gray-40; + font-size: $fs14; + .content { + padding: 2px 5px; + &.expired { + background-color: $color-warning-lighter; + border-radius: $br4; + color: $color-gray-40; + } + } + } + + &.access-token-created { + word-break: break-all; + } + + &.actions { + position: relative; + } + } +} + +.access-tokens-modal { + .action-buttons { + gap: 10px; + + .cancel-button { + border: 1px solid $color-gray-30; + background: $color-canvas; + border-radius: $br3; + padding: 0.5rem 1rem; + cursor: pointer; + margin-right: 8px; + + &:hover { + background: $color-gray-20; + } + } + } + .access-token-created { + position: relative; + word-break: break-all; + + .custom-input input { + background-color: $color-success-lighter; + border: 0; + padding: 0 0 0 15px; + } + } + + .help-icon { + border: none; + height: 40px; + width: 40px; + position: absolute; + top: 0; + right: 0; + cursor: pointer; + background-color: $color-success-lighter; + + svg { + fill: $color-gray-30; + } + + &:hover { + svg { + fill: $color-gray-60; + } + } + } + + .token-created-info { + font-size: $fs12; + color: $color-gray-40; + } +} + +.dashboard-settings { + a { + color: $df-secondary; + } + .form-container { + width: 800px; + margin: 80px auto auto 120px; + form { + width: 468px; + .fields-row { + .custom-input, + .custom-select { + flex-direction: column-reverse; + label { + position: relative; + text-transform: uppercase; + color: $df-primary; + font-size: 11px; + margin-bottom: 12px; + margin-left: -4px; + } + input, + select { + background-color: $db-tertiary; + border-radius: 8px; + border-color: transparent; + color: $df-primary; + padding: 0 15px; + &:focus { + outline: 1px solid $da-primary; + } + ::placeholder { + color: $df-secondary; + } + } + .help-icon { + bottom: 12px; + top: auto; + svg { + fill: $df-secondary; + } + } + &.disabled { + input { + background-color: $db-primary; + border-color: $db-cuaternary; + color: $df-secondary; + } + } + .input-container { + background-color: $db-tertiary; + border-radius: 8px; + border-color: transparent; + margin-top: 22px; + .main-content { + label { + position: absolute; + top: -24px; + } + span { + color: $df-primary; + } + } + &:focus { + border: 1px solid $da-primary; + } + } + textarea { + border-radius: 8px; + padding: 12px 14px; + background-color: $db-tertiary; + color: $df-primary; + border: none; + &:focus { + outline: 1px solid $da-primary; + } + } + } + } + .field-title { + color: $df-primary; + } + .field-title:not(:first-child) { + margin-top: 64px; + } + + .field-text { + color: $df-secondary; + } + button, + .btn-secondary { + width: 100%; + font-size: 11px; + text-transform: uppercase; + background-color: $db-tertiary; + color: $df-primary; + &:hover { + color: $da-primary; + background-color: $db-cuaternary; + } + } + hr { + display: none; + } + } + .links { + margin-top: 12px; + } + } +} diff --git a/frontend/src/app/main/ui/settings/profile.cljs b/frontend/src/app/main/ui/settings/profile.cljs index dd5ab9eef3..fc98794451 100644 --- a/frontend/src/app/main/ui/settings/profile.cljs +++ b/frontend/src/app/main/ui/settings/profile.cljs @@ -5,6 +5,7 @@ ;; Copyright (c) KALEIDOS INC (ns app.main.ui.settings.profile + (:require-macros [app.main.style :as stl]) (:require [app.common.spec :as us] [app.config :as cf] @@ -15,6 +16,7 @@ [app.main.store :as st] [app.main.ui.components.file-uploader :refer [file-uploader]] [app.main.ui.components.forms :as fm] + [app.main.ui.context :as ctx] [app.main.ui.icons :as i] [app.util.dom :as dom] [app.util.i18n :as i18n :refer [tr]] @@ -41,48 +43,85 @@ (mf/defc profile-form [] - (let [profile (mf/deref refs/profile) + (let [new-css-system (mf/use-ctx ctx/new-css-system) + + profile (mf/deref refs/profile) form (fm/use-form :spec ::profile-form :initial profile :validators [(fm/validate-length :fullname fm/max-length-allowed (tr "auth.name.too-long")) (fm/validate-not-empty :fullname (tr "auth.name.not-all-space"))])] - [:& fm/form {:on-submit on-submit - :form form - :class "profile-form"} - [:div.fields-row - [:& fm/input - {:type "text" - :name :fullname - :label (tr "dashboard.your-name")}]] + (if new-css-system + [:& fm/form {:on-submit on-submit + :form form + :class (stl/css :profile-form)} + [:div {:class (stl/css :fields-row)} + [:& fm/input + {:type "text" + :name :fullname + :label (tr "dashboard.your-name")}]] - [:div.fields-row - [:& fm/input - {:type "email" - :name :email - :disabled true - :help-icon i/at - :label (tr "dashboard.your-email")}] + [:div {:class (stl/css :fields-row)} + [:& fm/input + {:type "email" + :name :email + :disabled true + :help-icon i/at + :label (tr "dashboard.your-email")}] - [:div.options - [:div.change-email - [:a {:on-click #(modal/show! :change-email {})} - (tr "dashboard.change-email")]]]] + [:div {:class (stl/css :options)} + [:div.change-email + [:a {:on-click #(modal/show! :change-email {})} + (tr "dashboard.change-email")]]]] - [:> fm/submit-button* - {:label (tr "dashboard.save-settings") - :disabled (empty? (:touched @form))}] + [:> fm/submit-button* + {:label (tr "dashboard.save-settings") + :disabled (empty? (:touched @form))}] - [:div.links - [:div.link-item - [:a {:on-click #(modal/show! :delete-account {}) - :data-test "remove-acount-btn"} - (tr "dashboard.remove-account")]]]])) + [:div {:class (stl/css :links)} + [:div {:class (stl/css :link-item)} + [:a {:on-click #(modal/show! :delete-account {}) + :data-test "remove-acount-btn"} + (tr "dashboard.remove-account")]]]] + + ;; OLD + [:& fm/form {:on-submit on-submit + :form form + :class "profile-form"} + [:div.fields-row + [:& fm/input + {:type "text" + :name :fullname + :label (tr "dashboard.your-name")}]] + + [:div.fields-row + [:& fm/input + {:type "email" + :name :email + :disabled true + :help-icon i/at + :label (tr "dashboard.your-email")}] + + [:div.options + [:div.change-email + [:a {:on-click #(modal/show! :change-email {})} + (tr "dashboard.change-email")]]]] + + [:> fm/submit-button* + {:label (tr "dashboard.save-settings") + :disabled (empty? (:touched @form))}] + + [:div.links + [:div.link-item + [:a {:on-click #(modal/show! :delete-account {}) + :data-test "remove-acount-btn"} + (tr "dashboard.remove-account")]]]]))) ;; --- Profile Photo Form (mf/defc profile-photo-form [] - (let [file-input (mf/use-ref nil) + (let [new-css-system (mf/use-ctx ctx/new-css-system) + file-input (mf/use-ref nil) profile (mf/deref refs/profile) photo (cf/resolve-profile-photo-url profile) on-image-click #(dom/click (mf/ref-val file-input)) @@ -91,23 +130,44 @@ (fn [file] (st/emit! (du/update-photo file)))] - [:form.avatar-form - [:div.image-change-field - [:span.update-overlay {:on-click on-image-click} (tr "labels.update")] - [:img {:src photo}] - [:& file-uploader {:accept "image/jpeg,image/png" - :multi false - :ref file-input - :on-selected on-file-selected - :data-test "profile-image-input"}]]])) + (if new-css-system + [:form {:class (stl/css :avatar-form)} + [:div {:class (stl/css :image-change-field)} + [:span {:class (stl/css :update-overlay) + :on-click on-image-click} (tr "labels.update")] + [:img {:src photo}] + [:& file-uploader {:accept "image/jpeg,image/png" + :multi false + :ref file-input + :on-selected on-file-selected + :data-test "profile-image-input"}]]] + ;; OLD + [:form.avatar-form + [:div.image-change-field + [:span.update-overlay {:on-click on-image-click} (tr "labels.update")] + [:img {:src photo}] + [:& file-uploader {:accept "image/jpeg,image/png" + :multi false + :ref file-input + :on-selected on-file-selected + :data-test "profile-image-input"}]]]))) ;; --- Profile Page (mf/defc profile-page [] - (mf/with-effect [] - (dom/set-html-title (tr "title.settings.profile"))) - [:div.dashboard-settings - [:div.form-container.two-columns - [:& profile-photo-form] - [:& profile-form]]]) + (let [new-css-system (mf/use-ctx ctx/new-css-system)] + (mf/with-effect [] + (dom/set-html-title (tr "title.settings.profile"))) + (if new-css-system + [:div {:class (stl/css :dashboard-settings)} + [:div {:class (stl/css :form-container :two-columns)} + [:& profile-photo-form] + [:& profile-form]]] + + ;; OLD + [:div.dashboard-settings + [:div.form-container.two-columns + [:& profile-photo-form] + [:& profile-form]]]))) + diff --git a/frontend/src/app/main/ui/settings/profile.scss b/frontend/src/app/main/ui/settings/profile.scss new file mode 100644 index 0000000000..aa7e88cbca --- /dev/null +++ b/frontend/src/app/main/ui/settings/profile.scss @@ -0,0 +1,642 @@ +@import "common/dependencies/colors"; + +$br3: 3px; +$br4: 4px; +$br8: 8px; +$br6: 6px; +$fs12: 0.75rem; +$fs14: 0.875rem; +$fs16: 1rem; +$fs18: 1.125rem; +$fs22: 1.375rem; +$fs24: 1.5rem; +$fs36: 2.25rem; +$fw400: 400; +$fw500: 500; +$fw600: 600; +$fw700: 700; +$lh-088: 0.88; +$lh-115: 1.15; // original $title-lh-sm +$lh-500: 5; // original $title-lh-sm +$size-1: 0.25rem; +$size-2: 0.5rem; +$size-4: 1rem; +$size-5: 1.5rem; +$size-6: 2rem; + +.form-container, +.generic-form { + display: flex; + justify-content: center; + flex-direction: column; + + .forms-container { + display: flex; + margin-top: 40px; + width: 536px; + justify-content: center; + } + + form { + display: flex; + flex-direction: column; + // flex-basis: 368px; + } + + .fields-row { + margin-bottom: 20px; + flex-direction: column; + + .options { + display: flex; + justify-content: flex-end; + font-size: $fs14; + margin-top: 13px; + } + } + + .field { + margin-bottom: 20px; + } + + h1 { + font-size: $fs36; + color: #2c233e; + margin-bottom: 20px; + } + + .subtitle { + font-size: $fs24; + color: #2c233e; + margin-bottom: 20px; + } + + .notification-icon { + justify-content: center; + display: flex; + margin-bottom: 3rem; + + svg { + fill: $color-gray-60; + height: 40%; + width: 40%; + } + } + + .notification-text { + font-size: $fs18; + color: $color-gray-60; + margin-bottom: 20px; + } + + .notification-text-email { + background: $color-gray-10; + border-radius: $br3; + color: $color-gray-60; + font-size: $fs18; + font-weight: $fw500; + margin: 1.5rem 0 2.5rem 0; + padding: 1rem; + text-align: center; + } + + h2 { + font-size: $fs24; + color: $color-gray-60; + // height: 40px; + display: flex; + align-items: center; + } + + a { + &:hover { + text-decoration: underline; + } + } + + p { + color: $color-gray-60; + } + + hr { + border-color: $color-gray-20; + } +} + +.dashboard-header { + display: flex; + align-items: center; + justify-content: space-between; + background-color: $color-white; + height: 63px; + padding: $size-1 $size-4 $size-1 $size-2; + position: relative; + z-index: 10; + user-select: none; + &.team { + display: grid; + grid-template-columns: 20% 1fr 20%; + } + + .element-name { + margin-right: $size-2; + } + + .btn-secondary { + flex-shrink: 0; + z-index: 10; + height: 32px; + svg { + height: 16px; + width: 16px; + } + } + + svg { + fill: $color-black; + height: 14px; + margin-right: $size-1; + width: 14px; + } + + nav { + display: flex; + align-items: flex-end; + justify-content: center; + z-index: 1; + + ul { + display: flex; + font-size: $fs14; + justify-content: center; + margin: 0; + } + + li { + a { + display: flex; + align-items: center; + flex-basis: 140px; + border-bottom: 3px solid transparent; + color: $color-gray-30; + height: 40px; + padding: $size-1 $size-5; + font-weight: $fw400; + &:hover { + color: $color-black; + text-decoration: none; + } + } + + &.active { + a { + color: $color-black; + border-color: $color-primary; + } + } + } + } + + .dashboard-title { + display: flex; + align-items: center; + margin-left: 13px; + + h1 { + color: $color-black; + display: flex; + flex-shrink: 0; + font-size: $fs22; + font-weight: $fw600; + z-index: 10; + user-select: all; + } + + .context-menu.is-open { + margin-top: 10px; + } + } + + .icon { + display: flex; + align-items: center; + cursor: pointer; + margin-left: $size-2; + z-index: 10; + + svg { + fill: $color-gray-40; + width: 15px; + height: 15px; + + &:hover { + fill: $color-primary-dark; + } + } + } + + .dashboard-buttons { + display: flex; + justify-content: flex-end; + align-items: center; + } + + .dashboard-header-actions { + display: flex; + } + + .pin-icon { + margin: 0 $size-2 0 $size-5; + background-color: transparent; + border: none; + svg { + fill: $color-gray-20; + } + + &.active { + svg { + fill: $color-gray-50; + } + } + } +} + +.dashboard-settings { + display: flex; + width: 100%; + justify-content: center; + align-items: center; + + .form-container { + margin-top: 50px; + display: flex; + max-width: 368px; + margin-bottom: 2rem; + width: 100%; + + &.two-columns { + max-width: 536px; + justify-content: space-between; + flex-direction: row; + } + + h2 { + margin-bottom: 1rem; + } + } + + .avatar-form { + display: flex; + flex-direction: column; + width: 120px; + min-width: 120px; + + img { + border-radius: 50%; + flex-shrink: 0; + height: 120px; + margin-right: $size-4; + width: 120px; + } + + .image-change-field { + position: relative; + width: 120px; + height: 120px; + + .update-overlay { + opacity: 0; + cursor: pointer; + position: absolute; + width: 121px; + height: 121px; + border-radius: 50%; + font-size: $fs24; + color: $color-white; + line-height: $lh-500; // Original value was 120px; 120px/24px = 500% => $lh-500 + text-align: center; + background: $color-primary-dark; + z-index: 14; + } + + input[type="file"] { + width: 120px; + height: 120px; + position: absolute; + opacity: 0; + cursor: pointer; + top: 0; + z-index: 15; + } + + &:hover { + .update-overlay { + opacity: 0.8; + } + } + } + } + + .profile-form { + display: flex; + flex-direction: column; + max-width: 368px; + width: 100%; + + .newsletter-subs { + border-bottom: 1px solid $color-gray-20; + border-top: 1px solid $color-gray-20; + padding: 30px 0; + margin-bottom: 31px; + + .newsletter-title { + font-family: "worksans", sans-serif; + color: $color-gray-30; + font-size: $fs14; + } + + label { + font-family: "worksans", sans-serif; + color: $color-gray-60; + font-size: $fs12; + margin-right: -17px; + margin-bottom: 13px; + } + + .info { + font-family: "worksans", sans-serif; + color: $color-gray-30; + font-size: $fs12; + margin-bottom: 8px; + } + + .input-checkbox label { + align-items: flex-start; + } + } + } + + .options-form, + .password-form { + h2 { + font-size: $fs14; + margin-bottom: 20px; + } + } +} + +.dashboard-access-tokens { + display: flex; + flex-direction: column; + align-items: center; + + .access-tokens-hero-container { + max-width: 1000px; + width: 100%; + display: flex; + flex-direction: column; + } + + .access-tokens-hero { + font-size: $fs14; + padding: $size-6; + background-color: $color-white; + margin-top: $size-6; + display: flex; + justify-content: space-between; + + .desc { + width: 80%; + color: $color-gray-40; + h2 { + margin-bottom: $size-4; + color: $color-black; + } + p { + font-size: $fs16; + } + } + + .btn-primary { + flex-shrink: 0; + } + } + + .access-tokens-empty { + text-align: center; + max-width: 1000px; + width: 100%; + padding: $size-6; + display: flex; + flex-direction: column; + justify-content: center; + align-items: center; + border: 1px dashed $color-gray-20; + color: $color-gray-40; + margin-top: 12px; + min-height: 136px; + } + + .table-row { + background-color: $color-white; + display: grid; + grid-template-columns: 1fr 43% 12px; + height: 63px; + &:not(:first-child) { + margin-top: 8px; + } + } + + .table-field { + &.name { + color: $color-gray-60; + } + + &.expiration-date { + color: $color-gray-40; + font-size: $fs14; + .content { + padding: 2px 5px; + &.expired { + background-color: $color-warning-lighter; + border-radius: $br4; + color: $color-gray-40; + } + } + } + + &.access-token-created { + word-break: break-all; + } + + &.actions { + position: relative; + } + } +} + +.access-tokens-modal { + .action-buttons { + gap: 10px; + + .cancel-button { + border: 1px solid $color-gray-30; + background: $color-canvas; + border-radius: $br3; + padding: 0.5rem 1rem; + cursor: pointer; + margin-right: 8px; + + &:hover { + background: $color-gray-20; + } + } + } + .access-token-created { + position: relative; + word-break: break-all; + + .custom-input input { + background-color: $color-success-lighter; + border: 0; + padding: 0 0 0 15px; + } + } + + .help-icon { + border: none; + height: 40px; + width: 40px; + position: absolute; + top: 0; + right: 0; + cursor: pointer; + background-color: $color-success-lighter; + + svg { + fill: $color-gray-30; + } + + &:hover { + svg { + fill: $color-gray-60; + } + } + } + + .token-created-info { + font-size: $fs12; + color: $color-gray-40; + } +} + +.dashboard-settings { + a { + color: $df-secondary; + } + .form-container { + width: 800px; + margin: 80px auto auto 120px; + form { + width: 468px; + .fields-row { + .custom-input, + .custom-select { + flex-direction: column-reverse; + label { + position: relative; + text-transform: uppercase; + color: $df-primary; + font-size: 11px; + margin-bottom: 12px; + margin-left: -4px; + } + input, + select { + background-color: $db-tertiary; + border-radius: 8px; + border-color: transparent; + color: $df-primary; + padding: 0 15px; + &:focus { + outline: 1px solid $da-primary; + } + ::placeholder { + color: $df-secondary; + } + } + .help-icon { + bottom: 12px; + top: auto; + svg { + fill: $df-secondary; + } + } + &.disabled { + input { + background-color: $db-primary; + border-color: $db-cuaternary; + color: $df-secondary; + } + } + .input-container { + background-color: $db-tertiary; + border-radius: 8px; + border-color: transparent; + margin-top: 22px; + .main-content { + label { + position: absolute; + top: -24px; + } + span { + color: $df-primary; + } + } + &:focus { + border: 1px solid $da-primary; + } + } + textarea { + border-radius: 8px; + padding: 12px 14px; + background-color: $db-tertiary; + color: $df-primary; + border: none; + &:focus { + outline: 1px solid $da-primary; + } + } + } + } + .field-title { + color: $df-primary; + } + .field-title:not(:first-child) { + margin-top: 64px; + } + + .field-text { + color: $df-secondary; + } + button, + .btn-secondary { + width: 100%; + font-size: 11px; + text-transform: uppercase; + background-color: $db-tertiary; + color: $df-primary; + &:hover { + color: $da-primary; + background-color: $db-cuaternary; + } + } + hr { + display: none; + } + } + .links { + margin-top: 12px; + } + } +} diff --git a/frontend/src/app/main/ui/settings/sidebar.cljs b/frontend/src/app/main/ui/settings/sidebar.cljs index 8c077cb61d..4edbc733f7 100644 --- a/frontend/src/app/main/ui/settings/sidebar.cljs +++ b/frontend/src/app/main/ui/settings/sidebar.cljs @@ -5,12 +5,14 @@ ;; Copyright (c) KALEIDOS INC (ns app.main.ui.settings.sidebar + (:require-macros [app.main.style :as stl]) (:require [app.config :as cf] [app.main.data.events :as ev] [app.main.data.modal :as modal] [app.main.data.users :as du] [app.main.store :as st] + [app.main.ui.context :as ctx] [app.main.ui.dashboard.sidebar :refer [profile-section]] [app.main.ui.icons :as i] [app.util.i18n :as i18n :refer [tr]] @@ -21,7 +23,8 @@ (mf/defc sidebar-content [{:keys [profile section] :as props}] - (let [profile? (= section :settings-profile) + (let [new-css-system (mf/use-ctx ctx/new-css-system) + profile? (= section :settings-profile) password? (= section :settings-password) options? (= section :settings-options) feedback? (= section :settings-feedback) @@ -66,55 +69,112 @@ (st/emit! (modal/show {:type :onboarding})) (st/emit! (modal/show {:type :release-notes :version version}))))))] - [:div.sidebar-content - [:div.sidebar-content-section - [:div.back-to-dashboard {:on-click go-dashboard} - [:span.icon i/arrow-down] - [:span.text (tr "labels.dashboard")]]] - [:hr] - - [:div.sidebar-content-section - [:ul.sidebar-nav.no-overflow - [:li {:class (when profile? "current") - :on-click go-settings-profile} - i/user - [:span.element-title (tr "labels.profile")]] - - [:li {:class (when password? "current") - :on-click go-settings-password} - i/lock - [:span.element-title (tr "labels.password")]] - - [:li {:class (when options? "current") - :on-click go-settings-options - :data-test "settings-profile"} - i/tree - [:span.element-title (tr "labels.settings")]] - - (when (contains? cf/flags :access-tokens) - [:li {:class (when access-tokens? "current") - :on-click go-settings-access-tokens - :data-test "settings-access-tokens"} - i/icon-key - [:span.element-title (tr "labels.access-tokens")]]) - + (if new-css-system + [:div {:class (stl/css :sidebar-content)} + [:div {:class (stl/css :sidebar-content-section)} + [:div {:class (stl/css :back-to-dashboard) + :on-click go-dashboard} + [:span {:class (stl/css :icon)} i/arrow-down] + [:span {:class (stl/css :text)} (tr "labels.dashboard")]]] [:hr] - [:li {:on-click show-release-notes :data-test "release-notes"} - i/pencil - [:span.element-title (tr "labels.release-notes")]] + [:div {:class (stl/css :sidebar-content-section)} + [:ul {:class (stl/css :sidebar-nav :no-overflow)} + [:li {:class (when profile? (stl/css :current)) + :on-click go-settings-profile} + i/user + [:span {:class (stl/css :element-title)} (tr "labels.profile")]] - (when (contains? cf/flags :user-feedback) - [:li {:class (when feedback? "current") - :on-click go-settings-feedback} - i/msg-info - [:span.element-title (tr "labels.give-feedback")]])]]])) + [:li {:class (when password? (stl/css :current)) + :on-click go-settings-password} + i/lock + [:span {:class (stl/css :element-title)} (tr "labels.password")]] + + [:li {:class (when options? (stl/css :current)) + :on-click go-settings-options + :data-test "settings-profile"} + i/tree + [:span {:class (stl/css :element-title)} (tr "labels.settings")]] + + (when (contains? cf/flags :access-tokens) + [:li {:class (when access-tokens? (stl/css :current)) + :on-click go-settings-access-tokens + :data-test "settings-access-tokens"} + i/icon-key + [:span {:class (stl/css :element-title)} (tr "labels.access-tokens")]]) + + [:hr] + + [:li {:on-click show-release-notes :data-test "release-notes"} + i/pencil + [:span {:class (stl/css :element-title)} (tr "labels.release-notes")]] + + (when (contains? cf/flags :user-feedback) + [:li {:class (when feedback? (stl/css :current)) + :on-click go-settings-feedback} + i/msg-info + [:span {:class (stl/css :element-title)} (tr "labels.give-feedback")]])]]] + + ;; OLD + [:div.sidebar-content + [:div.sidebar-content-section + [:div.back-to-dashboard {:on-click go-dashboard} + [:span.icon i/arrow-down] + [:span.text (tr "labels.dashboard")]]] + [:hr] + + [:div.sidebar-content-section + [:ul.sidebar-nav.no-overflow + [:li {:class (when profile? "current") + :on-click go-settings-profile} + i/user + [:span.element-title (tr "labels.profile")]] + + [:li {:class (when password? "current") + :on-click go-settings-password} + i/lock + [:span.element-title (tr "labels.password")]] + + [:li {:class (when options? "current") + :on-click go-settings-options + :data-test "settings-profile"} + i/tree + [:span.element-title (tr "labels.settings")]] + + (when (contains? cf/flags :access-tokens) + [:li {:class (when access-tokens? "current") + :on-click go-settings-access-tokens + :data-test "settings-access-tokens"} + i/icon-key + [:span.element-title (tr "labels.access-tokens")]]) + + [:hr] + + [:li {:on-click show-release-notes :data-test "release-notes"} + i/pencil + [:span.element-title (tr "labels.release-notes")]] + + (when (contains? cf/flags :user-feedback) + [:li {:class (when feedback? "current") + :on-click go-settings-feedback} + i/msg-info + [:span.element-title (tr "labels.give-feedback")]])]]]))) (mf/defc sidebar {::mf/wrap [mf/memo]} [{:keys [profile locale section]}] - [:div.dashboard-sidebar.settings - [:& sidebar-content {:profile profile - :section section}] - [:& profile-section {:profile profile - :locale locale}]]) + (let [new-css-system (mf/use-ctx ctx/new-css-system)] + (if new-css-system + [:div {:class (stl/css :dashboard-sidebar :settings)} + [:& sidebar-content {:profile profile + :section section}] + [:& profile-section {:profile profile + :locale locale}]] + + ;; OLD + [:div.dashboard-sidebar.settings + [:& sidebar-content {:profile profile + :section section}] + [:& profile-section {:profile profile + :locale locale}]]))) + diff --git a/frontend/src/app/main/ui/settings/sidebar.scss b/frontend/src/app/main/ui/settings/sidebar.scss new file mode 100644 index 0000000000..bc77f93fb6 --- /dev/null +++ b/frontend/src/app/main/ui/settings/sidebar.scss @@ -0,0 +1,922 @@ +@import "common/dependencies/colors"; + +$fs14: 0.875rem; +$fs24: 1.5rem; +$lh-500: 5; +$fs12: 0.75rem; +$fs16: 1rem; +$fw400: 400; +$size-2: 0.5rem; +$size-3: 0.75rem; +$size-4: 1rem; +$size-6: 2rem; +$br3: 3px; +$br4: 4px; +$br5: 5px; +$fw700: 700; + +.dashboard-sidebar { + grid-row: 1 / span 2; + grid-column: 1 / span 2; + + background-color: $db-primary; + border-right: 1px solid $db-cuaternary; + margin: 0 1rem 0 0; + padding: 1rem 0 0 0; + + z-index: 1; + display: flex; + flex-direction: column; + height: 100%; +} + +.sidebar-content { + display: flex; + flex-direction: column; + height: 100%; + overflow-y: auto; + padding: 0; + + hr { + border-color: transparent; + margin: 0.8rem 15px; + } + + .back-to-dashboard { + .icon svg { + fill: $df-secondary; + } + .text { + color: $df-primary; + } + } +} + +.dashboard-sidebar { + background-color: $color-white; + z-index: 1; + display: flex; + flex-direction: column; + height: 100%; + padding-top: $size-2; + + .sidebar-content { + display: flex; + flex-direction: column; + height: 100%; + overflow-y: auto; + padding: 0; + + //hr { + // border-color: $color-gray-10; + // margin: 1rem 15px; + //} + } + + .sidebar-team-switch { + position: relative; + display: flex; + margin: 5px 15px; + + .teams-dropdown { + left: 0; + top: 50px; + z-index: 12; + max-height: 30rem; + min-width: 234px; + overflow-y: auto; + } + + .options-dropdown { + right: 2px; + top: 50px; + z-index: 12; + max-height: 30rem; + min-width: 162px; + } + + .switch-content { + height: 40px; + display: flex; + width: 100%; + border: 1px solid $color-gray-10; + border-radius: $br5; + align-items: center; + } + + .switch-options { + display: flex; + max-width: 22px; + min-width: 28px; + border-left: 1px solid $color-gray-10; + justify-content: center; + align-items: center; + cursor: pointer; + background-color: transparent; + border: none; + svg { + width: 15px; + height: 13px; + fill: $color-gray-60; + } + } + + .current-team { + cursor: pointer; + display: flex; + align-items: center; + flex-grow: 1; + font-size: $fs14; + padding: 0px 10px; + background-color: transparent; + border: none; + } + + .team-name { + flex-grow: 1; + display: flex; + height: 40px; + align-items: center; + + &.action { + .team-icon { + border-radius: 50%; + background-color: $color-gray-10; + height: 24px; + margin-right: 10px; + padding: 6px; + width: 24px; + + svg { + height: 12px; + width: 12px; + } + } + + &:hover { + .team-icon { + background-color: $color-primary; + } + } + + .team-text { + width: 150px; + } + } + + .team-icon { + display: flex; + align-items: center; + padding-right: 10px; + + svg { + width: 23px; + height: 23px; + fill: $color-gray-60; + } + + img { + border-radius: 50%; + flex-shrink: 0; + height: 23px; + width: 23px; + } + } + + .team-text { + color: $color-gray-60; + // @include text-ellipsis; + width: 130px; + text-align: left; + } + + .icon { + margin-left: auto; + svg { + fill: $color-gray-60; + } + } + } + + .switch-icon { + display: flex; + align-items: center; + justify-content: center; + svg { + width: 10px; + height: 10px; + fill: $color-gray-60; + } + } + } + + .sidebar-empty-placeholder { + padding: 10px 12px; + color: $color-gray-30; + display: flex; + align-items: flex-start; + + .icon { + padding: 0px 10px; + svg { + fill: $color-gray-30; + width: 12px; + height: 12px; + } + } + .text { + font-size: $fs12; + } + } + + .sidebar-nav { + display: flex; + flex-direction: column; + overflow-y: auto; + margin: 0; + user-select: none; + + // TODO: should be deprecated / unclear name + &.dashboard-common { + overflow: unset; + } + + &.no-overflow { + overflow: unset; + } + + & > li { + align-items: center; + cursor: pointer; + display: flex; + flex-shrink: 0; + padding: $size-2; + a { + font-weight: $fw400; + width: 100%; + &:hover { + text-decoration: none; + } + } + + svg { + fill: $color-black; + margin-right: 8px; + height: $size-3; + width: $size-3; + } + + span.element-title { + color: $color-gray-60; + font-size: $fs14; + overflow: hidden; + text-overflow: ellipsis; + white-space: nowrap; + } + + &::before { + background-color: transparent; + border-radius: $br3; + content: ""; + height: 26px; + margin-right: $size-2; + width: 4px; + } + + &.recent-projects { + svg { + fill: $color-white; + } + } + + & .edit-wrapper { + border: 1px solid $color-gray-10; + border-radius: $br3; + display: flex; + width: 100%; + } + + input.element-title { + border: 0; + height: 30px; + padding: 5px; + margin: 0; + width: 100%; + background-color: $color-white; + } + + .close { + background-color: $color-white; + cursor: pointer; + padding-left: 5px; + + svg { + fill: $color-gray-30; + height: 15px; + transform: rotate(45deg) translateY(7px); + width: 15px; + margin: 0; + } + } + + .element-subtitle { + color: $color-gray-20; + font-style: italic; + } + + &:hover { + &::before { + background-color: $color-gray-10; + } + } + + &.current { + a { + font-weight: $fw700; + } + + &::before { + background-color: $color-primary; + } + } + + &.dragging { + //background-color: color.adjust($color-primary, $alpha: -0.69); + } + } + } + + .sidebar-search { + align-items: center; + background-color: $color-white; + border: 1px solid $color-gray-10; + border-radius: $br5; + display: flex; + margin: 5px 15px; + + .input-text { + background: transparent; + border: 0; + color: $color-gray-60; + font-size: $fs14; + padding: 6px; + margin: 0; + max-width: 195px; + width: 100%; + height: 40px; + } + + &:focus, + &:focus-within { + border-color: $color-black; + } + + .search, + .clear-search { + align-items: center; + cursor: pointer; + display: flex; + height: 22px; + margin-left: auto; + padding: 0 $size-2; + width: 32px; + + svg { + fill: $color-gray-30; + height: 15px; + width: 15px; + } + } + + .clear-search svg { + transform: rotate(45deg); + + &:hover { + fill: $color-danger; + } + } + } + + &.profile-bar { + background-color: $color-gray-10; + + .dashboard-sidebar-inside { + display: none; + } + } +} + +.dashboard-sidebar { + &.settings { + .back-to-dashboard { + padding: 12px 18px; + font-size: $fs14; + cursor: pointer; + display: flex; + + .icon { + display: flex; + align-items: center; + margin-right: 14px; + } + + .text { + color: $color-gray-60; + } + + svg { + fill: $color-gray-60; + transform: rotate(90deg); + width: 12px; + height: 12px; + } + } + } +} + +.dashboard-settings { + display: flex; + width: 100%; + justify-content: center; + align-items: center; + + .form-container { + margin-top: 50px; + display: flex; + max-width: 368px; + margin-bottom: 2rem; + width: 100%; + + &.two-columns { + max-width: 536px; + justify-content: space-between; + flex-direction: row; + } + + h2 { + margin-bottom: 1rem; + } + } + + .avatar-form { + display: flex; + flex-direction: column; + width: 120px; + min-width: 120px; + + img { + border-radius: 50%; + flex-shrink: 0; + height: 120px; + margin-right: $size-4; + width: 120px; + } + + .image-change-field { + position: relative; + width: 120px; + height: 120px; + + .update-overlay { + opacity: 0; + cursor: pointer; + position: absolute; + width: 121px; + height: 121px; + border-radius: 50%; + font-size: $fs24; + color: $color-white; + line-height: $lh-500; // Original value was 120px; 120px/24px = 500% => $lh-500 + text-align: center; + background: $color-primary-dark; + z-index: 14; + } + + input[type="file"] { + width: 120px; + height: 120px; + position: absolute; + opacity: 0; + cursor: pointer; + top: 0; + z-index: 15; + } + + &:hover { + .update-overlay { + opacity: 0.8; + } + } + } + } + + .profile-form { + display: flex; + flex-direction: column; + max-width: 368px; + width: 100%; + + .newsletter-subs { + border-bottom: 1px solid $color-gray-20; + border-top: 1px solid $color-gray-20; + padding: 30px 0; + margin-bottom: 31px; + + .newsletter-title { + font-family: "worksans", sans-serif; + color: $color-gray-30; + font-size: $fs14; + } + + label { + font-family: "worksans", sans-serif; + color: $color-gray-60; + font-size: $fs12; + margin-right: -17px; + margin-bottom: 13px; + } + + .info { + font-family: "worksans", sans-serif; + color: $color-gray-30; + font-size: $fs12; + margin-bottom: 8px; + } + + .input-checkbox label { + align-items: flex-start; + } + } + } + + .options-form, + .password-form { + h2 { + font-size: $fs14; + margin-bottom: 20px; + } + } +} + +.dashboard-access-tokens { + display: flex; + flex-direction: column; + align-items: center; + + .access-tokens-hero-container { + max-width: 1000px; + width: 100%; + display: flex; + flex-direction: column; + } + + .access-tokens-hero { + font-size: $fs14; + padding: $size-6; + background-color: $color-white; + margin-top: $size-6; + display: flex; + justify-content: space-between; + + .desc { + width: 80%; + color: $color-gray-40; + h2 { + margin-bottom: $size-4; + color: $color-black; + } + p { + font-size: $fs16; + } + } + + .btn-primary { + flex-shrink: 0; + } + } + + .access-tokens-empty { + text-align: center; + max-width: 1000px; + width: 100%; + padding: $size-6; + display: flex; + flex-direction: column; + justify-content: center; + align-items: center; + border: 1px dashed $color-gray-20; + color: $color-gray-40; + margin-top: 12px; + min-height: 136px; + } + + .table-row { + background-color: $color-white; + display: grid; + grid-template-columns: 1fr 43% 12px; + height: 63px; + &:not(:first-child) { + margin-top: 8px; + } + } + + .table-field { + &.name { + color: $color-gray-60; + } + + &.expiration-date { + color: $color-gray-40; + font-size: $fs14; + .content { + padding: 2px 5px; + &.expired { + background-color: $color-warning-lighter; + border-radius: $br4; + color: $color-gray-40; + } + } + } + + &.access-token-created { + word-break: break-all; + } + + &.actions { + position: relative; + } + } +} + +.access-tokens-modal { + .action-buttons { + gap: 10px; + + .cancel-button { + border: 1px solid $color-gray-30; + background: $color-canvas; + border-radius: $br3; + padding: 0.5rem 1rem; + cursor: pointer; + margin-right: 8px; + + &:hover { + background: $color-gray-20; + } + } + } + .access-token-created { + position: relative; + word-break: break-all; + + .custom-input input { + background-color: $color-success-lighter; + border: 0; + padding: 0 0 0 15px; + } + } + + .help-icon { + border: none; + height: 40px; + width: 40px; + position: absolute; + top: 0; + right: 0; + cursor: pointer; + background-color: $color-success-lighter; + + svg { + fill: $color-gray-30; + } + + &:hover { + svg { + fill: $color-gray-60; + } + } + } + + .token-created-info { + font-size: $fs12; + color: $color-gray-40; + } +} + +.dashboard-sidebar { + background-color: $db-primary; + border-right: 1px solid $db-cuaternary; + grid-row: 1 / span 2; + grid-column: 1 / span 2; + margin: 0 1rem 0 0; + padding: 1rem 0 0 0; + + .dropdown { + background-color: $db-tertiary; + border: 1px solid $db-cuaternary; + border-radius: 8px; + min-width: 252px; + + .separator { + border-color: transparent; + margin-top: 10px; + } + + li { + border-radius: 8px; + height: 40px; + margin: 5px; + + &:hover { + background-color: $db-cuaternary; + } + } + + &.options-dropdown { + li { + color: $df-primary; + &.warning { + color: $color-danger; + } + } + } + } + + .sidebar-content { + .back-to-dashboard { + .icon { + svg { + fill: $df-secondary; + } + } + .text { + color: $df-primary; + } + } + .sidebar-team-switch { + .switch-content { + background-color: $db-tertiary; + border-radius: 8px; + border-color: transparent; + height: 48px; + + .current-team { + border-right: 1px solid $db-primary; + height: 100%; + } + + svg { + fill: $df-secondary; + } + + .team-name { + .team-text { + color: $df-primary; + width: 145px; + } + } + } + } + + .teams-dropdown { + background-color: $db-tertiary; + border-radius: 8px; + border: 1px solid $db-cuaternary; + min-width: 248px; + + li { + border-radius: 8px; + height: 42px; + padding: 0 5px; + margin: 5px; + + .team-text { + color: $df-primary; + width: 165px; + } + svg { + fill: $df-secondary; + } + + &:hover { + background-color: $db-cuaternary; + .team-icon { + &.new-team { + background-color: $da-primary; + svg { + fill: $db-secondary; + } + } + } + } + + .team-icon { + &.new-team { + background-color: $db-cuaternary; + } + } + } + } + + .sidebar-search { + background-color: $db-tertiary; + border-color: transparent; + border-radius: 8px; + margin-bottom: 2rem; + margin-top: 0; + position: relative; + + .input-text { + border-radius: 8px; + color: $df-primary; + max-width: 100%; + padding: 6px 10px; + + &:focus { + border: 1px solid $da-primary; + } + } + ::placeholder { + color: $df-secondary; + } + + .search { + position: absolute; + top: 10px; + right: 2px; + } + } + + .sidebar-nav { + li { + padding: 0.6rem 0.6rem 0.6rem 1.4rem; + &.current { + background-color: $db-cuaternary; + a { + font-weight: 400; + span { + color: $da-primary; + } + } + span { + color: $da-primary; + } + } + &:hover { + background-color: $db-cuaternary; + } + span { + color: $df-secondary; + } + &::before { + display: none; + } + + svg { + display: none; + } + } + } + } + + .sidebar-empty-placeholder { + color: $df-secondary; + } + + // Profile sidebar + .profile-section { + background-color: $db-tertiary; + border-top: 1px solid $db-cuaternary; + + span { + color: $df-primary; + } + + .dashboard-comments-section { + border-color: transparent; + border-radius: 8px; + background-color: $db-primary; + height: 32px; + width: 32px; + + .button { + border-radius: 8px; + background-color: $db-primary; + height: 32px; + width: 32px; + + svg { + fill: $df-secondary; + } + + &:hover { + background-color: $db-cuaternary; + + svg { + fill: $da-primary; + } + } + } + } + } +} From c1882af124a987d67782e7c84c533ea6bd340960 Mon Sep 17 00:00:00 2001 From: "alonso.torres" Date: Tue, 21 Nov 2023 14:56:51 +0100 Subject: [PATCH 4/6] :lipstick: Cleaned styles for new UI --- .../styles/common/refactor/animations.scss | 22 + .../styles/common/refactor/basic-rules.scss | 1 - .../common/refactor/common-dashboard.scss | 168 ++ .../common/refactor/common-refactor.scss | 17 + .../styles/common/refactor/fonts.scss | 1 + .../styles/common/refactor/spacing.scss | 213 +- .../styles/main/layouts/main-layout.scss | 1089 ---------- frontend/src/app/main/style.clj | 2 +- frontend/src/app/main/ui/comments.scss | 8 + .../src/app/main/ui/components/forms.cljs | 36 +- .../src/app/main/ui/components/forms.scss | 13 +- frontend/src/app/main/ui/dashboard.cljs | 2 +- frontend/src/app/main/ui/dashboard.scss | 19 +- .../src/app/main/ui/dashboard/comments.cljs | 112 +- .../src/app/main/ui/dashboard/comments.scss | 597 +----- frontend/src/app/main/ui/dashboard/files.scss | 235 +-- frontend/src/app/main/ui/dashboard/fonts.cljs | 22 +- frontend/src/app/main/ui/dashboard/fonts.scss | 875 +++----- frontend/src/app/main/ui/dashboard/grid.cljs | 28 +- frontend/src/app/main/ui/dashboard/grid.scss | 838 ++++---- .../app/main/ui/dashboard/inline_edition.cljs | 1 - .../app/main/ui/dashboard/inline_edition.scss | 53 + .../src/app/main/ui/dashboard/libraries.scss | 750 +------ .../app/main/ui/dashboard/placeholder.cljs | 6 +- .../app/main/ui/dashboard/placeholder.scss | 118 +- .../src/app/main/ui/dashboard/projects.cljs | 19 +- .../src/app/main/ui/dashboard/projects.scss | 856 ++------ .../src/app/main/ui/dashboard/search.cljs | 4 - .../src/app/main/ui/dashboard/search.scss | 332 +-- .../src/app/main/ui/dashboard/sidebar.cljs | 239 ++- .../src/app/main/ui/dashboard/sidebar.scss | 278 ++- frontend/src/app/main/ui/dashboard/team.cljs | 9 +- frontend/src/app/main/ui/dashboard/team.scss | 1780 ++++++----------- .../src/app/main/ui/dashboard/templates.scss | 199 +- frontend/src/app/main/ui/settings.cljs | 4 + frontend/src/app/main/ui/settings.scss | 856 ++------ .../app/main/ui/settings/access_tokens.cljs | 1 - .../app/main/ui/settings/access_tokens.scss | 1011 ++-------- .../src/app/main/ui/settings/feedback.cljs | 3 +- .../src/app/main/ui/settings/feedback.scss | 701 +------ .../src/app/main/ui/settings/options.cljs | 12 +- .../src/app/main/ui/settings/options.scss | 647 +----- .../src/app/main/ui/settings/password.cljs | 5 +- .../src/app/main/ui/settings/password.scss | 647 +----- .../src/app/main/ui/settings/profile.cljs | 10 +- .../src/app/main/ui/settings/profile.scss | 809 +++----- .../src/app/main/ui/settings/sidebar.cljs | 5 - .../src/app/main/ui/settings/sidebar.scss | 995 ++------- 48 files changed, 3271 insertions(+), 11377 deletions(-) create mode 100644 frontend/resources/styles/common/refactor/animations.scss create mode 100644 frontend/resources/styles/common/refactor/common-dashboard.scss diff --git a/frontend/resources/styles/common/refactor/animations.scss b/frontend/resources/styles/common/refactor/animations.scss new file mode 100644 index 0000000000..44cdf2ee65 --- /dev/null +++ b/frontend/resources/styles/common/refactor/animations.scss @@ -0,0 +1,22 @@ +// 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 + +@mixin animation($delay, $duration, $animation) { + -webkit-animation-delay: $delay; + -webkit-animation-duration: $duration; + -webkit-animation-name: $animation; + -webkit-animation-fill-mode: both; + + -moz-animation-delay: $delay; + -moz-animation-duration: $duration; + -moz-animation-name: $animation; + -moz-animation-fill-mode: both; + + animation-delay: $delay; + animation-duration: $duration; + animation-name: $animation; + animation-fill-mode: both; +} diff --git a/frontend/resources/styles/common/refactor/basic-rules.scss b/frontend/resources/styles/common/refactor/basic-rules.scss index 0cb5aea6fc..cd3b867629 100644 --- a/frontend/resources/styles/common/refactor/basic-rules.scss +++ b/frontend/resources/styles/common/refactor/basic-rules.scss @@ -854,5 +854,4 @@ align-items: center; justify-content: normal; width: 100%; - overflow: hidden; } diff --git a/frontend/resources/styles/common/refactor/common-dashboard.scss b/frontend/resources/styles/common/refactor/common-dashboard.scss new file mode 100644 index 0000000000..dc0a728e01 --- /dev/null +++ b/frontend/resources/styles/common/refactor/common-dashboard.scss @@ -0,0 +1,168 @@ +// 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" as *; + +.dashboard-header { + align-items: center; + display: flex; + height: $s-64; + justify-content: space-between; + padding: $s-4 $s-16 $s-4 $s-8; + position: relative; + user-select: none; + + &.team { + display: grid; + grid-template-columns: 20% 1fr 20%; + } + + .element-name { + margin-right: $s-8; + } + + .btn-secondary { + flex-shrink: 0; + height: $s-32; + svg { + height: $s-16; + width: $s-16; + } + } + + svg { + fill: $db-secondary; + height: $s-12; + margin-right: $s-4; + width: $s-12; + } + + nav { + display: flex; + align-items: flex-end; + justify-content: center; + + ul { + display: flex; + font-size: $fs-14; + justify-content: center; + margin: 0; + } + + li { + a { + display: flex; + align-items: center; + flex-basis: $s-140; + border-bottom: $s-3 solid transparent; + color: $df-secondary; + height: $s-40; + padding: $s-4 $s-24; + font-weight: $fw400; + &:hover { + color: $db-secondary; + text-decoration: none; + } + } + } + } + + .dashboard-title { + display: flex; + align-items: center; + margin-left: $s-12; + + h1 { + color: $df-primary; + display: block; + flex-shrink: 0; + font-size: $fs-24; + font-weight: $fw400; + max-width: $s-712; + overflow: hidden; + text-overflow: ellipsis; + user-select: all; + white-space: nowrap; + width: 100%; + } + + .context-menu.is-open { + margin-top: $s-8; + } + } + + .icon { + display: flex; + align-items: center; + cursor: pointer; + margin-left: $s-8; + + svg { + fill: $df-secondary; + width: $s-16; + height: $s-16; + + &:hover { + fill: $da-tertiary; + } + } + } + + .dashboard-buttons { + display: flex; + justify-content: flex-end; + align-items: center; + } + + .dashboard-header-actions { + display: flex; + } + + .pin-icon { + margin: 0 $s-8 0 $s-24; + background-color: transparent; + border: none; + svg { + fill: $df-secondary; + } + + &.active { + svg { + fill: $db-cuaternary; + } + } + } + .dashboard-header-options { + li { + a { + font-size: $s-16; + color: $df-secondary; + border-color: transparent; + &:hover { + color: $df-primary; + } + } + &.active { + a { + color: $df-primary; + } + } + } + } +} + +.btn-primary { + @extend .button-primary; + text-transform: uppercase; +} + +.btn-secondary { + @extend .button-secondary; + color: $df-primary; + font-size: $fs-12; + text-transform: uppercase; + padding: 0 $s-16; +} diff --git a/frontend/resources/styles/common/refactor/common-refactor.scss b/frontend/resources/styles/common/refactor/common-refactor.scss index 2793e6f16d..c1033735c8 100644 --- a/frontend/resources/styles/common/refactor/common-refactor.scss +++ b/frontend/resources/styles/common/refactor/common-refactor.scss @@ -16,4 +16,21 @@ @import "common/refactor/z-index.scss"; @import "common/refactor/mixins.scss"; @import "common/refactor/focus.scss"; +@import "common/refactor/animations.scss"; @import "common/refactor/basic-rules.scss"; + +// Variables to use the library colors +$db-primary: var(--color-background-primary); +$db-secondary: var(--color-background-secondary); +$db-tertiary: var(--color-background-tertiary); +$db-cuaternary: var(--color-background-quaternary); +$db-subtle: var(--color-background-subtle); +$db-disabled: var(--color-background-disabled); + +$df-primary: var(--color-foreground-primary); +$df-secondary: var(--color-foreground-secondary); +$df-tertiary: var(--color-foreground-tertiary); +$da-primary: var(--color-accent-primary); +$da-primary-muted: var(--color-accent-primary-muted); +$da-secondary: var(--color-accent-secondary); +$da-tertiary: var(--color-accent-tertiary); diff --git a/frontend/resources/styles/common/refactor/fonts.scss b/frontend/resources/styles/common/refactor/fonts.scss index ef4df7c8cd..40d1dcb872 100644 --- a/frontend/resources/styles/common/refactor/fonts.scss +++ b/frontend/resources/styles/common/refactor/fonts.scss @@ -16,6 +16,7 @@ $fs-12: math.div(12, $fs-base) + rem; $fs-14: math.div(14, $fs-base) + rem; $fs-16: math.div(16, $fs-base) + rem; $fs-24: math.div(24, $fs-base) + rem; +$fs-36: math.div(36, $fs-base) + rem; // Font weight $fw400: 400; // Regular (CSS value: 'normal') diff --git a/frontend/resources/styles/common/refactor/spacing.scss b/frontend/resources/styles/common/refactor/spacing.scss index 2b046700cb..c80afc3a32 100644 --- a/frontend/resources/styles/common/refactor/spacing.scss +++ b/frontend/resources/styles/common/refactor/spacing.scss @@ -10,77 +10,142 @@ $s-0: 0px; $s-1: 1px; $s-2: math.div(0.25rem, 2); $s-3: calc($s-1 + $s-2); -$s-4: var(--s-4); -$s-6: calc($s-2 + $s-4); -$s-8: calc(var(--s-4) * 2); -$s-12: calc(var(--s-4) * 3); -$s-16: calc(var(--s-4) * 4); -$s-20: calc(var(--s-4) * 5); -$s-24: calc(var(--s-4) * 6); -$s-28: calc(var(--s-4) * 7); -$s-32: calc(var(--s-4) * 8); -$s-36: calc(var(--s-4) * 9); -$s-40: calc(var(--s-4) * 10); -$s-44: calc(var(--s-4) * 11); -$s-48: calc(var(--s-4) * 12); -$s-52: calc(var(--s-4) * 13); -$s-56: calc(var(--s-4) * 14); -$s-60: calc(var(--s-4) * 15); -$s-64: calc(var(--s-4) * 16); -$s-68: calc(var(--s-4) * 17); -$s-72: calc(var(--s-4) * 18); -$s-76: calc(var(--s-4) * 19); -$s-80: calc(var(--s-4) * 20); -$s-84: calc(var(--s-4) * 21); -$s-92: calc(var(--s-4) * 23); -$s-96: calc(var(--s-4) * 24); -$s-100: calc(var(--s-4) * 25); -$s-104: calc(var(--s-4) * 26); -$s-108: calc(var(--s-4) * 27); -$s-116: calc(var(--s-4) * 29); -$s-120: calc(var(--s-4) * 30); -$s-124: calc(var(--s-4) * 31); -$s-128: calc(var(--s-4) * 32); -$s-136: calc(var(--s-4) * 34); -$s-140: calc(var(--s-4) * 35); -$s-148: calc(var(--s-4) * 37); -$s-156: calc(var(--s-4) * 39); -$s-152: calc(var(--s-4) * 38); -$s-160: calc(var(--s-4) * 40); -$s-168: calc(var(--s-4) * 42); -$s-172: calc(var(--s-4) * 43); -$s-180: calc(var(--s-4) * 45); -$s-184: calc(var(--s-4) * 46); -$s-188: calc(var(--s-4) * 47); -$s-192: calc(var(--s-4) * 48); -$s-196: calc(var(--s-4) * 49); -$s-200: calc(var(--s-4) * 50); -$s-216: calc(var(--s-4) * 54); -$s-220: calc(var(--s-4) * 55); -$s-228: calc(var(--s-4) * 57); -$s-240: calc(var(--s-4) * 60); -$s-248: calc(var(--s-4) * 62); -$s-252: calc(var(--s-4) * 63); -$s-256: calc(var(--s-4) * 64); -$s-260: calc(var(--s-4) * 65); -$s-272: calc(var(--s-4) * 68); -$s-276: calc(var(--s-4) * 69); -$s-280: calc(var(--s-4) * 70); -$s-284: calc(var(--s-4) * 71); -$s-300: calc(var(--s-4) * 75); -$s-320: calc(var(--s-4) * 80); -$s-348: calc(var(--s-4) * 87); -$s-356: calc(var(--s-4) * 89); -$s-364: calc(var(--s-4) * 91); -$s-380: calc(var(--s-4) * 95); -$s-400: calc(var(--s-4) * 100); -$s-408: calc(var(--s-4) * 102); -$s-440: calc(var(--s-4) * 110); -$s-480: calc(var(--s-4) * 120); -$s-500: calc(var(--s-4) * 125); -$s-512: calc(var(--s-4) * 128); -$s-520: calc(var(--s-4) * 130); -$s-640: calc(var(--s-4) * 160); -$s-664: calc(var(--s-4) * 166); -$s-712: calc(var(--s-4) * 178); -$s-736: calc(var(--s-4) * 184); +$s-4: 0.25rem; +$s-6: #{0.25 + math.div(0.25, 2)}rem; + +// To calculate: +// https://docs.google.com/spreadsheets/d/1YVEfudB3bdO2ZOo5azZLJzZgA0Fkt1C85-1jVjuSYXg/edit?usp=sharing +$s-8: #{0.25 * 2}rem; +$s-12: #{0.25 * 3}rem; +$s-16: #{0.25 * 4}rem; +$s-20: #{0.25 * 5}rem; +$s-24: #{0.25 * 6}rem; +$s-28: #{0.25 * 7}rem; +$s-32: #{0.25 * 8}rem; +$s-36: #{0.25 * 9}rem; +$s-40: #{0.25 * 10}rem; +$s-44: #{0.25 * 11}rem; +$s-48: #{0.25 * 12}rem; +$s-52: #{0.25 * 13}rem; +$s-56: #{0.25 * 14}rem; +$s-60: #{0.25 * 15}rem; +$s-64: #{0.25 * 16}rem; +$s-68: #{0.25 * 17}rem; +$s-72: #{0.25 * 18}rem; +$s-76: #{0.25 * 19}rem; +$s-80: #{0.25 * 20}rem; +$s-84: #{0.25 * 21}rem; +$s-88: #{0.25 * 22}rem; +$s-92: #{0.25 * 23}rem; +$s-96: #{0.25 * 24}rem; +$s-100: #{0.25 * 25}rem; +$s-104: #{0.25 * 26}rem; +$s-108: #{0.25 * 27}rem; +$s-112: #{0.25 * 28}rem; +$s-116: #{0.25 * 29}rem; +$s-120: #{0.25 * 30}rem; +$s-124: #{0.25 * 31}rem; +$s-128: #{0.25 * 32}rem; +$s-132: #{0.25 * 33}rem; +$s-136: #{0.25 * 34}rem; +$s-140: #{0.25 * 35}rem; +$s-144: #{0.25 * 36}rem; +$s-148: #{0.25 * 37}rem; +$s-152: #{0.25 * 38}rem; +$s-156: #{0.25 * 39}rem; +$s-160: #{0.25 * 40}rem; +$s-164: #{0.25 * 41}rem; +$s-168: #{0.25 * 42}rem; +$s-172: #{0.25 * 43}rem; +$s-176: #{0.25 * 44}rem; +$s-180: #{0.25 * 45}rem; +$s-184: #{0.25 * 46}rem; +$s-188: #{0.25 * 47}rem; +$s-192: #{0.25 * 48}rem; +$s-196: #{0.25 * 49}rem; +$s-200: #{0.25 * 50}rem; +$s-204: #{0.25 * 51}rem; +$s-208: #{0.25 * 52}rem; +$s-212: #{0.25 * 53}rem; +$s-216: #{0.25 * 54}rem; +$s-220: #{0.25 * 55}rem; +$s-224: #{0.25 * 56}rem; +$s-228: #{0.25 * 57}rem; +$s-232: #{0.25 * 58}rem; +$s-236: #{0.25 * 59}rem; +$s-240: #{0.25 * 60}rem; +$s-244: #{0.25 * 61}rem; +$s-248: #{0.25 * 62}rem; +$s-252: #{0.25 * 63}rem; +$s-256: #{0.25 * 64}rem; +$s-260: #{0.25 * 65}rem; +$s-264: #{0.25 * 66}rem; +$s-268: #{0.25 * 67}rem; +$s-272: #{0.25 * 68}rem; +$s-276: #{0.25 * 69}rem; +$s-280: #{0.25 * 70}rem; +$s-284: #{0.25 * 71}rem; +$s-288: #{0.25 * 72}rem; +$s-292: #{0.25 * 73}rem; +$s-296: #{0.25 * 74}rem; +$s-300: #{0.25 * 75}rem; +$s-304: #{0.25 * 76}rem; +$s-308: #{0.25 * 77}rem; +$s-312: #{0.25 * 78}rem; +$s-316: #{0.25 * 79}rem; +$s-320: #{0.25 * 80}rem; +$s-324: #{0.25 * 81}rem; +$s-328: #{0.25 * 82}rem; +$s-332: #{0.25 * 83}rem; +$s-336: #{0.25 * 84}rem; +$s-340: #{0.25 * 85}rem; +$s-344: #{0.25 * 86}rem; +$s-348: #{0.25 * 87}rem; +$s-352: #{0.25 * 88}rem; +$s-356: #{0.25 * 89}rem; +$s-360: #{0.25 * 90}rem; +$s-364: #{0.25 * 91}rem; +$s-368: #{0.25 * 92}rem; +$s-372: #{0.25 * 93}rem; +$s-376: #{0.25 * 94}rem; +$s-380: #{0.25 * 95}rem; +$s-384: #{0.25 * 96}rem; +$s-388: #{0.25 * 97}rem; +$s-392: #{0.25 * 98}rem; +$s-396: #{0.25 * 99}rem; +$s-400: #{0.25 * 100}rem; +$s-404: #{0.25 * 101}rem; +$s-408: #{0.25 * 102}rem; +$s-412: #{0.25 * 103}rem; +$s-416: #{0.25 * 104}rem; +$s-420: #{0.25 * 105}rem; +$s-424: #{0.25 * 106}rem; +$s-428: #{0.25 * 107}rem; +$s-432: #{0.25 * 108}rem; +$s-436: #{0.25 * 109}rem; +$s-440: #{0.25 * 110}rem; +$s-444: #{0.25 * 111}rem; +$s-448: #{0.25 * 112}rem; +$s-452: #{0.25 * 113}rem; +$s-456: #{0.25 * 114}rem; +$s-460: #{0.25 * 115}rem; +$s-464: #{0.25 * 116}rem; +$s-468: #{0.25 * 117}rem; +$s-472: #{0.25 * 118}rem; +$s-476: #{0.25 * 119}rem; +$s-480: #{0.25 * 120}rem; +$s-484: #{0.25 * 121}rem; +$s-488: #{0.25 * 122}rem; +$s-492: #{0.25 * 123}rem; +$s-496: #{0.25 * 124}rem; +$s-500: #{0.25 * 125}rem; +$s-512: #{0.25 * 128}rem; +$s-520: #{0.25 * 130}rem; +$s-580: #{0.25 * 145}rem; +$s-612: #{0.25 * 153}rem; +$s-640: #{0.25 * 160}rem; +$s-664: #{0.25 * 166}rem; +$s-712: #{0.25 * 178}rem; +$s-736: #{0.25 * 184}rem; +$s-800: #{0.25 * 200}rem; +$s-1000: #{0.25 * 250}rem; diff --git a/frontend/resources/styles/main/layouts/main-layout.scss b/frontend/resources/styles/main/layouts/main-layout.scss index a9ba4a0aeb..fbe768447a 100644 --- a/frontend/resources/styles/main/layouts/main-layout.scss +++ b/frontend/resources/styles/main/layouts/main-layout.scss @@ -50,1092 +50,3 @@ display: flex; flex-direction: column; } - -// NEW DASHBOARD CSS - -.delete-me-dashboard-layout-refactor { - background-color: $db-primary; - display: grid; - grid-template-rows: 50px 1fr; - grid-template-columns: 40px 256px 1fr; - height: 100vh; - - .context-menu-items { - background-color: $db-tertiary; - border: 1px solid $db-cuaternary; - border-radius: 8px; - min-width: 252px; - - svg { - fill: $df-secondary; - } - - .separator { - border-color: transparent; - margin-top: 10px; - } - - a, - .context-menu-action { - border-radius: 8px; - height: 40px; - margin: 5px; - color: $df-primary; - cursor: pointer; - width: auto; - - &:hover { - background-color: $db-cuaternary; - } - } - } - - .dashboard-sidebar { - background-color: $db-primary; - border-right: 1px solid $db-cuaternary; - grid-row: 1 / span 2; - grid-column: 1 / span 2; - margin: 0 1rem 0 0; - padding: 1rem 0 0 0; - - .dropdown { - background-color: $db-tertiary; - border: 1px solid $db-cuaternary; - border-radius: 8px; - min-width: 252px; - - .separator { - border-color: transparent; - margin-top: 10px; - } - - li { - border-radius: 8px; - height: 40px; - margin: 5px; - - &:hover { - background-color: $db-cuaternary; - } - } - - &.options-dropdown { - li { - color: $df-primary; - &.warning { - color: $color-danger; - } - } - } - } - - .sidebar-content { - .back-to-dashboard { - .icon { - svg { - fill: $df-secondary; - } - } - .text { - color: $df-primary; - } - } - .sidebar-team-switch { - .switch-content { - background-color: $db-tertiary; - border-radius: 8px; - border-color: transparent; - height: 48px; - - .current-team { - border-right: 1px solid $db-primary; - height: 100%; - } - - svg { - fill: $df-secondary; - } - - .team-name { - .team-text { - color: $df-primary; - width: 145px; - } - } - } - } - - .teams-dropdown { - background-color: $db-tertiary; - border-radius: 8px; - border: 1px solid $db-cuaternary; - min-width: 248px; - - li { - border-radius: 8px; - height: 42px; - padding: 0 5px; - margin: 5px; - - .team-text { - color: $df-primary; - width: 165px; - } - svg { - fill: $df-secondary; - } - - &:hover { - background-color: $db-cuaternary; - .team-icon { - &.new-team { - background-color: $da-primary; - svg { - fill: $db-secondary; - } - } - } - } - - .team-icon { - &.new-team { - background-color: $db-cuaternary; - } - } - } - } - - .sidebar-search { - background-color: $db-tertiary; - border-color: transparent; - border-radius: 8px; - margin-bottom: 2rem; - margin-top: 0; - position: relative; - - .input-text { - border-radius: 8px; - color: $df-primary; - max-width: 100%; - padding: 6px 10px; - - &:focus { - border: 1px solid $da-primary; - } - } - ::placeholder { - color: $df-secondary; - } - - .search { - position: absolute; - top: 10px; - right: 2px; - } - } - - .sidebar-nav { - li { - padding: 0.6rem 0.6rem 0.6rem 1.4rem; - &.current { - background-color: $db-cuaternary; - a { - font-weight: 400; - span { - color: $da-primary; - } - } - span { - color: $da-primary; - } - } - &:hover { - background-color: $db-cuaternary; - } - span { - color: $df-secondary; - } - &::before { - display: none; - } - - svg { - display: none; - } - } - } - } - - .sidebar-empty-placeholder { - color: $df-secondary; - } - - // Profile sidebar - .profile-section { - background-color: $db-tertiary; - border-top: 1px solid $db-cuaternary; - - span { - color: $df-primary; - } - - .dashboard-comments-section { - border-color: transparent; - border-radius: 8px; - background-color: $db-primary; - height: 32px; - width: 32px; - - .button { - border-radius: 8px; - background-color: $db-primary; - height: 32px; - width: 32px; - - svg { - fill: $df-secondary; - } - - &:hover { - background-color: $db-cuaternary; - - svg { - fill: $da-primary; - } - } - } - } - } - } - - // Dashboard layout - .dashboard-content { - grid-row: 1 / span 2; - padding: 1rem 1rem 0 0; - - .grid-empty-placeholder { - background-color: transparent; - - .create-new { - background-color: $db-tertiary; - border-radius: 8px; - border: none; - color: $df-primary; - text-transform: uppercase; - - &:hover { - background-color: $db-cuaternary; - color: $da-primary; - } - } - - &.search { - border: 1px solid $db-cuaternary; - border-radius: 8px; - .text { - color: $df-primary; - } - .icon { - svg { - fill: $df-secondary; - } - } - } - } - - // Settings - .dashboard-container { - background-color: transparent; - border-top: 1px solid $db-cuaternary; - - .dashboard-settings { - a { - color: $df-secondary; - } - .form-container { - width: 800px; - margin: 80px auto auto 120px; - form { - width: 468px; - .fields-row { - .custom-input, - .custom-select { - flex-direction: column-reverse; - label { - position: relative; - text-transform: uppercase; - color: $df-primary; - font-size: 11px; - margin-bottom: 12px; - margin-left: -4px; - } - input, - select { - background-color: $db-tertiary; - border-radius: 8px; - border-color: transparent; - color: $df-primary; - padding: 0 15px; - &:focus { - outline: 1px solid $da-primary; - } - ::placeholder { - color: $df-secondary; - } - } - .help-icon { - bottom: 12px; - top: auto; - svg { - fill: $df-secondary; - } - } - &.disabled { - input { - background-color: $db-primary; - border-color: $db-cuaternary; - color: $df-secondary; - } - } - .input-container { - background-color: $db-tertiary; - border-radius: 8px; - border-color: transparent; - margin-top: 22px; - .main-content { - label { - position: absolute; - top: -24px; - } - span { - color: $df-primary; - } - } - &:focus { - border: 1px solid $da-primary; - } - } - textarea { - border-radius: 8px; - padding: 12px 14px; - background-color: $db-tertiary; - color: $df-primary; - border: none; - &:focus { - outline: 1px solid $da-primary; - } - } - } - } - .field-title { - color: $df-primary; - } - .field-title:not(:first-child) { - margin-top: 64px; - } - - .field-text { - color: $df-secondary; - } - button, - .btn-secondary { - width: 100%; - font-size: 11px; - text-transform: uppercase; - background-color: $db-tertiary; - color: $df-primary; - &:hover { - color: $da-primary; - background-color: $db-cuaternary; - } - } - hr { - display: none; - } - } - .links { - margin-top: 12px; - } - } - } - - //Access tokens - .dashboard-access-tokens { - width: 800px; - margin-left: 120px; - margin-top: 80px; - .access-tokens-hero-container { - background-color: transparent; - .access-tokens-hero { - width: 468px; - flex-direction: column; - gap: 32px; - background-color: transparent; - margin: 0; - padding: 0; - .desc { - background-color: transparent; - width: 100%; - h2 { - color: $df-primary; - font-size: 24px; - font-weight: regular; - margin-bottom: 32px; - } - p { - color: $df-secondary; - margin-bottom: 0; - font-size: 14px; - } - } - button { - width: 100%; - font-size: 11px; - text-transform: uppercase; - background-color: $db-tertiary; - color: $df-primary; - &:hover { - color: $da-primary; - background-color: $db-cuaternary; - } - } - } - } - .dashboard-table { - width: 800px; - .table-rows { - padding-top: 0; - .table-row { - font-size: 14px; - min-height: 40px; - height: fit-content; - .name { - color: $df-primary; - max-width: 480px; - overflow: hidden; - text-overflow: ellipsis; - display: -webkit-box; - -webkit-line-clamp: 2; - -webkit-box-orient: vertical; - } - .expiration-date { - color: $df-secondary; - } - } - } - } - .access-tokens-empty { - width: 468px; - border: 1px solid $db-cuaternary; - border-radius: 8px; - margin-top: 32px; - font-size: 14px; - background-color: transparent; - color: $df-secondary; - } - } - - // Team webhooks - &.dashboard-team-webhooks { - width: 800px; - margin-left: 120px; - margin-top: 80px; - border: none; - align-items: flex-start; - .webhooks-hero-container { - width: 468px; - background-color: transparent; - .webhooks-hero { - width: 468px; - flex-direction: column; - gap: 32px; - background-color: transparent; - margin: 0; - padding: 0; - .desc { - background-color: transparent; - width: 100%; - h2 { - color: $df-primary; - font-size: 24px; - font-weight: regular; - margin-bottom: 32px; - } - p { - color: $df-secondary; - margin-bottom: 0; - font-size: 14px; - } - } - .btn-primary { - width: 100%; - font-size: 11px; - text-transform: uppercase; - background-color: $db-tertiary; - color: $df-primary; - &:hover { - color: $da-primary; - background-color: $db-cuaternary; - } - } - } - } - .dashboard-table { - width: 800px; - .table-rows { - padding-top: 0; - .table-row { - font-size: 14px; - min-height: 40px; - height: fit-content; - .name { - color: $df-primary; - max-width: 480px; - } - .expiration-date { - color: $df-secondary; - } - } - } - } - .webhooks-empty { - width: 468px; - border: 1px solid $db-cuaternary; - border-radius: 8px; - margin-top: 32px; - font-size: 14px; - background-color: transparent; - color: $df-secondary; - } - } - - // Members section - .dashboard-table { - .table-header { - background-color: transparent; - color: $df-secondary; - font-size: 12px; - text-transform: uppercase; - } - .table-rows { - .table-row { - background-color: $db-tertiary; - border-radius: 8px; - color: $df-primary; - .rol-selector { - background-color: $db-cuaternary; - border-color: transparent; - border-radius: 8px; - } - } - } - .member-info { - .member-name .you, - .member-email { - color: $df-secondary; - } - } - .status-badge { - border-radius: 8px; - color: $db-primary; - text-transform: uppercase; - } - .empty-invitations { - border: 1px solid $db-cuaternary; - border-radius: 8px; - color: $df-secondary; - } - } - .actions-dropdown, - .options-dropdown { - background-color: $db-tertiary; - border: 1px solid $db-cuaternary; - border-radius: 8px; - min-width: 252px; - - .separator { - border-color: transparent; - margin-top: 10px; - } - - li { - border-radius: 8px; - height: 40px; - margin: 5px; - color: $df-primary; - - &:hover { - background-color: $db-cuaternary; - } - } - - &.options-dropdown { - li { - color: $df-primary; - &.warning { - color: $color-danger; - } - } - } - } - } - - // Team settings - .horizontal-blocks { - flex-direction: column; - gap: 24px; - .block { - background-color: transparent; - .label { - color: $df-secondary; - font-size: 11px; - text-transform: uppercase; - } - .icon { - svg { - fill: $df-secondary; - } - } - .name, - .text { - color: $df-primary; - } - &.info-block { - padding-top: 180px; - .icon { - left: 0; - height: 120px; - width: 120px; - img { - width: 120px; - height: 120px; - } - .update-overlay { - background-color: $da-primary; - height: 120px; - width: 120px; - svg { - fill: $db-primary; - } - } - } - } - } - } - } - - .dashboard-header { - background-color: transparent; - .dashboard-title { - h1 { - color: $df-primary; - font-size: 24px; - font-weight: 400; - width: 100%; - text-overflow: ellipsis; - overflow: hidden; - white-space: nowrap; - display: block; - max-width: 700px; - } - } - .icon { - svg { - fill: $df-secondary; - } - } - - // Settings sub-menu - .dashboard-header-options { - li { - a { - font-size: 16px; - color: $df-secondary; - border-color: transparent; - &:hover { - color: $df-primary; - } - } - &.active { - a { - color: $df-primary; - } - } - } - } - } - - // Hero banners - .team-hero { - background-color: $db-tertiary; - border: none; - img { - border-radius: 4px; - margin-bottom: 0; - width: 230px; - } - .text { - .title { - color: $df-primary; - font-weight: 400; - } - .info { - color: $df-secondary; - a { - color: $da-primary; - } - } - } - svg { - fill: $df-secondary; - } - .invite { - height: 32px; - } - } - - .hero-projects { - .tutorial, - .walkthrough { - background-color: $db-tertiary; - border: none; - img { - border-radius: 4px; - margin-bottom: 0; - width: 230px; - } - .text { - .title { - color: $df-primary; - font-weight: 400; - } - .info { - color: $df-secondary; - a { - color: $da-primary; - } - } - } - svg { - fill: $df-secondary; - } - .invite { - height: 32px; - } - } - } - - // Dashboard content - .dashboard-project-row .project { - background-color: transparent; - - h2 { - color: $df-primary; - font-weight: 400; - } - span { - color: $df-secondary; - } - .project-actions { - svg { - fill: $df-primary; - } - .pin-icon { - svg.icon-pin-fill { - fill: $df-secondary; - } - } - } - } - - .dashboard-sidebar .sidebar-content hr { - border-color: transparent; - margin: 0.8rem 15px; - } - - .icon { - svg { - fill: $df-secondary; - } - } - - .btn-primary { - background-color: $da-tertiary; - border-radius: 8px; - color: $db-primary; - height: 32px; - text-transform: uppercase; - &:hover { - background-color: darken($da-tertiary, 10%); - color: $db-primary; - } - } - - .btn-secondary { - background-color: $db-tertiary; - text-transform: uppercase; - border: none; - color: $df-primary; - border-radius: 8px; - - &:hover { - background-color: $db-cuaternary; - color: $da-primary; - svg { - fill: $da-primary; - } - } - } - - // File cards - .dashboard-grid { - .grid-item { - &.project-th { - background-color: transparent; - border-radius: 8px; - padding-top: 0.3rem; - .info-wrapper { - cursor: pointer; - .item-info { - h3 { - color: $df-primary; - font-size: 16px; - font-weight: 400; - } - } - .date { - color: $df-secondary; - } - .project-th-actions { - .project-th-icon { - margin-top: 0; - .icon-actions { - fill: $df-secondary; - } - } - } - } - - &:hover { - background-color: $db-tertiary; - .grid-item-th { - border: none; - } - } - } - - .grid-item-th { - border-radius: 4px; - border: none; - cursor: pointer; - } - - .item-badge { - background-color: $da-primary; - border: none; - border-radius: 4px; - svg { - fill: $db-secondary; - } - } - } - } - - // Libraries slider - .dashboard-templates-section { - .title { - right: -24px; - button { - background-color: $db-cuaternary; - border: none; - span { - color: $df-primary; - font-weight: 400; - } - } - } - .content { - border-top-left-radius: 8px; - border: none; - background-color: $db-cuaternary; - - .template-card { - color: $df-primary; - padding: 0.2rem 0.3rem 1rem 0.3rem; - border-radius: 8px; - .img-container { - border: none; - img { - border-radius: 4px; - } - } - .card-name { - span { - font-size: 16px; - } - } - .template-link { - .template-link-title { - color: $df-primary; - font-weight: 400; - } - .template-link-text { - color: $df-secondary; - } - } - - &:hover { - background-color: $db-tertiary; - .img-container { - border: none; - } - } - } - } - } - - // Input edit - .edit-wrapper { - border: none; - input { - background-color: $db-primary !important; - outline: 1px solid $da-primary !important; - border-radius: 8px; - color: $df-primary !important; - font-size: 16px !important; - } - .close { - right: -8px; - svg { - fill: $df-secondary; - } - &:hover { - svg { - fill: $color-danger; - } - } - } - } - - // Inner sections - .dashboard-fonts { - background-color: $db-primary; - border-top: 1px solid $db-cuaternary; - - .dashboard-fonts-hero { - background-color: transparent; - .desc { - width: 70%; - h2 { - color: $df-primary; - font-weight: 400; - } - p { - color: $df-secondary; - font-size: 14px; - } - .banner { - background-color: $db-primary; - border-radius: 8px; - border: 1px solid $db-cuaternary; - color: $df-primary; - font-size: 12px; - .content { - span { - a { - color: $da-primary; - } - } - } - .icon { - background-color: transparent; - svg { - fill: $df-secondary; - } - } - &.warning { - background-color: $db-cuaternary; - } - } - } - } - - .installed-fonts-header { - background-color: transparent; - text-transform: uppercase; - color: $df-secondary; - } - - .fonts-placeholder { - border: 1px solid $db-cuaternary; - border-radius: 8px; - .icon { - svg { - fill: $df-secondary; - } - } - .label { - color: $df-secondary; - } - } - - .font-item { - background-color: $db-tertiary; - border-radius: 8px; - color: $df-secondary; - padding: 0.8rem 1.5rem; - min-height: auto; - margin-top: 4px; - &:not(:first-child) { - border: none; - } - .table-field { - color: $df-primary; - .variant { - background-color: $db-cuaternary; - border-radius: 8px; - margin-right: 4px; - padding-right: 4px; - } - } - } - - .font-item { - input { - background-color: $db-tertiary; - border-color: transparent; - border-radius: 8px; - color: $df-primary; - font-size: 14px; - &:focus { - outline: 1px solid $da-primary; - } - } - > .variants { - padding-left: 1rem; - } - } - - .installed-fonts-header { - padding-right: 0; - .search-input { - input { - background-color: $db-tertiary; - border-color: transparent; - border-radius: 8px; - color: $df-primary; - font-size: 14px; - height: 32px; - padding: 0 0.6rem; - width: 150px; - &:focus { - outline: 1px solid $da-primary; - } - &::placeholder { - color: $df-secondary; - } - } - } - } - } -} diff --git a/frontend/src/app/main/style.clj b/frontend/src/app/main/style.clj index cc113941da..4e275cdf79 100644 --- a/frontend/src/app/main/style.clj +++ b/frontend/src/app/main/style.clj @@ -24,7 +24,7 @@ (case kns "global" knm "old-css" (if (nil? *css-data*) knm "") - (or (get *css-data* (keyword knm)) knm))) + (or (get *css-data* (keyword knm)) (str "_not_found_" knm)))) (string? k) k)))) diff --git a/frontend/src/app/main/ui/comments.scss b/frontend/src/app/main/ui/comments.scss index d7a2e1de86..89fc247d70 100644 --- a/frontend/src/app/main/ui/comments.scss +++ b/frontend/src/app/main/ui/comments.scss @@ -9,6 +9,10 @@ // Comment-thread-group .thread-group { padding: 0 $s-12; + cursor: pointer; + border-radius: $br-8; + padding: $s-8 $s-16; + .section-title { @include titleTipography; height: $s-32; @@ -39,6 +43,10 @@ flex-direction: column; gap: $s-24; } + + &:hover { + background: $db-primary; + } } // Comment-thread diff --git a/frontend/src/app/main/ui/components/forms.cljs b/frontend/src/app/main/ui/components/forms.cljs index f148995a3a..ee64dc30e1 100644 --- a/frontend/src/app/main/ui/components/forms.cljs +++ b/frontend/src/app/main/ui/components/forms.cljs @@ -9,6 +9,7 @@ (:require [app.common.data :as d] [app.common.data.macros :as dm] + [app.main.ui.components.select :as cs] [app.main.ui.context :as ctx] [app.main.ui.hooks :as hooks] [app.main.ui.icons :as i] @@ -252,10 +253,10 @@ value (or (get-in @form [:data input-name]) default) cvalue (d/seek #(= value (:value %)) options) focus? (mf/use-state false) - on-change + + handle-change (fn [event] - (let [target (dom/get-target event) - value (dom/get-value target)] + (let [value (if (string? event) event (dom/get-target-val event))] (fm/on-input-change form input-name value))) on-focus @@ -267,33 +268,16 @@ (reset! focus? false))] (if new-css-system - [:div {:class (stl/css :custom-select)} - [:select {:value value - :on-change on-change - :on-focus on-focus - :on-blur on-blur - :disabled disabled - :data-test data-test} - (for [item options] - [:> :option (clj->js (cond-> {:key (:value item) :value (:value item)} - (:disabled item) (assoc :disabled "disabled") - (:hidden item) (assoc :style {:display "none"}))) - (:label item)])] - - [:div {:class (stl/css-case :input-container true - :disabled disabled - :focus @focus?)} - [:div {:class (stl/css :main-content)} - [:label {:class (stl/css :label)} label] - [:span {:class (stl/css :value)} (:label cvalue "")]] - - [:div {:class (stl/css :icon)} - i/arrow-refactor]]] + [:div {:class (stl/css :select-wrapper)} + [:& cs/select + {:default-value value + :options options + :on-change handle-change}]] [:div.custom-select [:select {:value value - :on-change on-change + :on-change handle-change :on-focus on-focus :on-blur on-blur :disabled disabled diff --git a/frontend/src/app/main/ui/components/forms.scss b/frontend/src/app/main/ui/components/forms.scss index 707b1fc639..8c022b06a8 100644 --- a/frontend/src/app/main/ui/components/forms.scss +++ b/frontend/src/app/main/ui/components/forms.scss @@ -23,12 +23,18 @@ padding: 0; cursor: pointer; color: var(--modal-title-foreground-color); - text-transform: none; + text-transform: uppercase; input { @extend .input-element; color: var(--input-foreground-color-active); width: calc(100% - $s-1); margin-top: 0; + + &:focus { + outline: none; + border: $s-1 solid var(--input-border-color-focus); + border-radius: $br-8; + } } // Input autofill input:-webkit-autofill, @@ -39,11 +45,6 @@ -webkit-box-shadow: 0 0 0 28px var(--input-background-color) inset !important; border: $s-1 solid var(--input-background-color); } - &:focus { - outline: none; - border: $s-1 solid var(--input-border-color-focus); - border-radius: $br-8; - } } &:global(.invalid) { input { diff --git a/frontend/src/app/main/ui/dashboard.cljs b/frontend/src/app/main/ui/dashboard.cljs index 4b7bc7bdf3..54894422e0 100644 --- a/frontend/src/app/main/ui/dashboard.cljs +++ b/frontend/src/app/main/ui/dashboard.cljs @@ -239,7 +239,7 @@ ;; components on team change. Many components assumes that the ;; team is already set so don't put the team into mf/deps. (when team - [:main {:class (stl/css :dashboard-layout-refactor :dashboard) + [:main {:class (stl/css :dashboard) :key (:id team)} [:& sidebar {:team team diff --git a/frontend/src/app/main/ui/dashboard.scss b/frontend/src/app/main/ui/dashboard.scss index 71d4d91e2b..42c45ba1a3 100644 --- a/frontend/src/app/main/ui/dashboard.scss +++ b/frontend/src/app/main/ui/dashboard.scss @@ -1,11 +1,22 @@ -@import "common/dependencies/colors"; +// 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 "refactor/common-refactor.scss" as *; .dashboard { background-color: $db-primary; display: grid; - grid-template-rows: 50px 1fr; - grid-template-columns: 40px 256px 1fr; + grid-template-columns: $s-40 $s-256 1fr; + grid-template-rows: $s-52 1fr; height: 100vh; + + :global(svg#loader-pencil) { + fill: $df-secondary; + width: $s-32; + } } .dashboard-content { @@ -13,5 +24,5 @@ flex-direction: column; position: relative; grid-row: 1 / span 2; - padding: 1rem 1rem 0 0; + padding: $s-16 $s-16 0 0; } diff --git a/frontend/src/app/main/ui/dashboard/comments.cljs b/frontend/src/app/main/ui/dashboard/comments.cljs index 4b1815b3a8..9f3b4e28a7 100644 --- a/frontend/src/app/main/ui/dashboard/comments.cljs +++ b/frontend/src/app/main/ui/dashboard/comments.cljs @@ -22,12 +22,40 @@ [potok.core :as ptk] [rumext.v2 :as mf])) +(mf/defc comments-icon + [{:keys [profile show? on-show-comments]}] + + (let [threads-map (mf/deref refs/comment-threads) + + tgroups + (->> (vals threads-map) + (sort-by :modified-at) + (reverse) + (dcm/apply-filters {} profile) + (dcm/group-threads-by-file-and-page)) + + handle-keydown + (mf/use-callback + (mf/deps on-show-comments) + (fn [event] + (when (kbd/enter? event) + (on-show-comments event))))] + + [:div {:class (stl/css :dashboard-comments-section)} + [:button + {:tab-index "0" + :on-click on-show-comments + :on-key-down handle-keydown + :data-test "open-comments" + :class (stl/css-case :button true + :open show? + :unread (boolean (seq tgroups)))} + i/chat]])) + (mf/defc comments-section - [{:keys [profile team]}] + [{:keys [profile team show? on-show-comments on-hide-comments]}] (let [new-css-system (mf/use-ctx ctx/new-css-system) - show-dropdown? (mf/use-state false) - show-dropdown (mf/use-fn #(reset! show-dropdown? true)) - hide-dropdown (mf/use-fn #(reset! show-dropdown? false)) + threads-map (mf/deref refs/comment-threads) users (mf/deref refs/current-team-comments-users) team-id (:id team) @@ -38,6 +66,13 @@ (dcm/apply-filters {} profile) (dcm/group-threads-by-file-and-page)) + handle-keydown + (mf/use-callback + (mf/deps on-hide-comments) + (fn [event] + (when (kbd/enter? event) + (on-hide-comments event)))) + on-navigate (mf/use-callback (fn [thread] @@ -48,42 +83,25 @@ (mf/deps team-id) (fn [] (st/emit! (dcm/retrieve-unread-comment-threads team-id)))) - + (mf/use-effect - (mf/deps @show-dropdown?) + (mf/deps show?) (fn [] - (when @show-dropdown? + (when show? (st/emit! (ptk/event ::ev/event {::ev/name "open-comment-notifications" ::ev/origin "dashboard"}))))) (if new-css-system [:div {:class (stl/css :dashboard-comments-section)} - [:div - {:tab-index "0" - :on-click show-dropdown - :on-key-down (fn [event] - (when (kbd/enter? event) - (show-dropdown event))) - :data-test "open-comments" - :class (stl/css-case :button true - :open @show-dropdown? - :unread (boolean (seq tgroups)))} - i/chat] - - [:& dropdown {:show @show-dropdown? :on-close hide-dropdown} + [:& dropdown {:show show? :on-close on-hide-comments} [:div {:class (stl/css :dropdown :comments-section :comment-threads-section)} [:div {:class (stl/css :header)} [:h3 (tr "labels.comments")] - [:span {:class (stl/css :close) - :tab-index (if @show-dropdown? - "0" - "-1") - :on-click hide-dropdown - :on-key-down (fn [event] - (when (kbd/enter? event) - (hide-dropdown event)))} i/close]] - - [:hr] + [:button + {:class (stl/css :close) + :tab-index (if show? "0" "-1") + :on-click on-hide-comments + :on-key-down handle-keydown} i/close]] (if (seq tgroups) [:div {:class (stl/css :thread-groups)} @@ -93,15 +111,12 @@ :show-file-name true :users users}] (for [tgroup (rest tgroups)] - [:* - [:hr] - - [:& cmt/comment-thread-group - {:group tgroup - :on-thread-click on-navigate - :show-file-name true - :users users - :key (:page-id tgroup)}]])] + [:& cmt/comment-thread-group + {:group tgroup + :on-thread-click on-navigate + :show-file-name true + :users users + :key (:page-id tgroup)}])] [:div {:class (stl/css :thread-groups-placeholder)} i/chat @@ -111,26 +126,23 @@ [:div.dashboard-comments-section [:div.button {:tab-index "0" - :on-click show-dropdown + :on-click on-show-comments :on-key-down (fn [event] (when (kbd/enter? event) - (show-dropdown event))) + (on-show-comments event))) :data-test "open-comments" - :class (dom/classnames :open @show-dropdown? + :class (dom/classnames :open show? :unread (boolean (seq tgroups)))} i/chat] - [:& dropdown {:show @show-dropdown? :on-close hide-dropdown} + [:& dropdown {:show show? :on-close on-hide-comments} [:div.dropdown.comments-section.comment-threads-section. [:div.header [:h3 (tr "labels.comments")] - [:span.close {:tab-index (if @show-dropdown? - "0" - "-1") - :on-click hide-dropdown - :on-key-down (fn [event] - (when (kbd/enter? event) - (hide-dropdown event)))} i/close]] + [:span.close {:tab-index (if show? "0" "-1") + :on-click on-hide-comments + :on-key-down handle-keydown} + i/close]] [:hr] diff --git a/frontend/src/app/main/ui/dashboard/comments.scss b/frontend/src/app/main/ui/dashboard/comments.scss index e16952e48e..9de57d692f 100644 --- a/frontend/src/app/main/ui/dashboard/comments.scss +++ b/frontend/src/app/main/ui/dashboard/comments.scss @@ -1,526 +1,131 @@ -@import "common/dependencies/colors"; -$fs12: 0.75rem; -$fs14: 0.875rem; -$size-2: 0.5rem; -$size-4: 1rem; -$size-5: 1.5rem; -$br2: 2px; -$br3: 3px; -$fw400: 400; -$fw700: 700; +// 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 -.dropdown { - position: absolute; - max-height: 30rem; - background-color: #ffffff; - border-radius: 2px; - box-shadow: 0px 2px 8px rgba(0, 0, 0, 0.25); - z-index: 12; - - background-color: #212426; - border: 1px solid #2e3434; - border-radius: 8px; - min-width: 252px; - - hr { - margin: 0; - border-color: #e3e3e3; - } -} - -.comments-section { - .thread-bubble { - position: absolute; - display: flex; - transform: translate(-15px, -15px); - - cursor: pointer; - pointer-events: auto; - background-color: $color-gray-10; - color: $color-gray-60; - border: 1px solid #b1b2b5; - box-sizing: border-box; - box-shadow: 0px 4px 4px rgba($color-black, 0.25); - - font-size: $fs12; - width: 30px; - height: 30px; - border-radius: 50%; - - display: flex; - align-items: center; - justify-content: center; - - &.resolved { - color: $color-gray-10; - background-color: $color-gray-50; - } - - &.unread { - background-color: $color-primary; - } - span { - user-select: none; - } - } - - .thread-content { - position: absolute; - pointer-events: auto; - margin-left: 10px; - background: $color-white; - border: 1px solid $color-gray-20; - box-sizing: border-box; - box-shadow: 0px 2px 8px rgba($color-black, 0.25); - border-radius: $br2; - min-width: 280px; - max-width: 280px; - user-select: text; - - .comments { - max-height: 420px; - min-height: 105px; - overflow-y: auto; - } - - hr { - border: 0; - height: 1px; - background-color: $color-gray-20; - margin: 0px 10px; - } - } - - .reply-form { - display: flex; - padding: 10px; - flex-direction: column; - - &.edit-form { - padding-bottom: 0px; - } - - textarea { - font-family: "worksans", sans-serif; - font-size: $fs12; - min-height: 32px; - outline: none; - overflow: hidden; - padding: $size-2; - resize: none; - width: 100%; - border-radius: $br2; - border: 1px solid $color-gray-20; - max-height: 4rem; - } - - .buttons { - margin-top: 10px; - display: flex; - justify-content: flex-end; - - input { - margin: 0px; - font-size: $fs14; - - &:not(:last-child) { - margin-right: 6px; - } - } - } - } - - .comment-container { - position: relative; - } - - .comment { - display: flex; - flex-direction: column; - padding: $size-4 $size-2; - - .author { - display: flex; - align-items: center; - height: 26px; - max-height: 26px; - position: relative; - - .name { - display: flex; - flex-direction: column; - - .fullname { - font-weight: $fw700; - color: $color-gray-60; - font-size: $fs12; - - // @include text-ellipsis; - width: 174px; - } - .timeago { - margin-top: -2px; - font-size: $fs12; - color: $color-gray-30; - } - } - - .avatar { - display: flex; - align-items: center; - padding-right: 6px; - - img { - border-radius: 50%; - flex-shrink: 0; - height: 24px; - width: 24px; - } - } - - .options-resolve { - position: absolute; - right: 20px; - top: 0px; - width: 16px; - height: 16px; - - cursor: pointer; - - svg { - width: 16px; - height: 16px; - fill: $color-gray-30; - } - } - - .options { - position: absolute; - right: -2px; - top: 2px; - height: 16px; - display: flex; - align-items: center; - cursor: pointer; - - .options-icon { - svg { - width: 14px; - height: 14px; - fill: $color-black; - } - } - } - } - - .content { - margin: $size-4 0; - font-size: $fs14; - color: $color-black; - .text { - margin: 0 $size-2 0 26px; - white-space: pre-wrap; - display: inline-block; - word-break: break-word; - } - } - } - - .comment-options-dropdown { - top: 7px; - right: 7px; - width: 150px; - - border: 1px solid #b1b2b5; - } -} - -.workspace-comment-threads-sidebar-header { - display: flex; - background-color: $color-black; - height: 34px; - align-items: center; - padding: 0px 9px; - color: $color-gray-10; - font-size: $fs12; - justify-content: space-between; - - .options { - display: flex; - margin-right: 3px; - cursor: pointer; - - .label { - padding-right: 8px; - } - - .icon { - display: flex; - align-items: center; - } - - svg { - fill: $color-gray-10; - width: 10px; - height: 10px; - } - } - - .dropdown { - top: 80px; - right: 7px; - } -} - -.comment-threads-section { - pointer-events: auto; - - .thread-groups { - height: calc(100% - 34px); - overflow-y: scroll; - hr { - border: 0; - height: 1px; - background-color: $color-gray-30; - margin: 0px 0px; - } - } - - .thread-group { - display: flex; - flex-direction: column; - font-size: $fs12; - - .section-title { - margin: 0px 10px; - margin-top: 15px; - - .icon { - margin-right: 4px; - } - - .label { - &.filename { - font-weight: $fw700; - } - } - - svg { - fill: $color-gray-10; - height: 10px; - width: 10px; - } - } - } - - .thread-bubble { - position: unset; - transform: unset; - width: 24px; - height: 24px; - margin-right: 6px; - box-shadow: unset; - } - - .comment { - cursor: pointer; - .author { - margin-bottom: $size-4; - .name { - display: flex; - - .fullname { - width: unset; - max-width: 170px; - color: $color-gray-20; - padding-right: 3px; - } - .timeago { - margin-top: unset; - color: $color-gray-20; - } - } - } - - .content { - margin-top: 0px; - color: $color-white; - - &.replies { - margin: 0 $size-2 0 26px; - display: flex; - .total-replies { - margin-right: 9px; - color: $color-info; - } - - .new-replies { - color: $color-primary; - } - } - } - } -} - -.viewer-comments-container { - width: 100%; - height: 100%; - z-index: 1; - position: absolute; - top: 0px; - left: 0px; -} - -.workspace-comments-container { - width: 100%; - height: 100%; - grid-column: 1 / span 2; - grid-row: 1 / span 2; - z-index: 1000; - pointer-events: none; - overflow: hidden; - user-select: text; - - .threads { - position: absolute; - top: 0px; - left: 0px; - } -} +@use "common/refactor/common-refactor.scss" as *; .dashboard-comments-section { - width: 25px; - height: 25px; display: flex; align-items: center; justify-content: center; - background-color: $color-dashboard; - border-radius: $br3; position: relative; + border-radius: $br-8; - .button { - width: 25px; - height: 25px; - display: flex; - align-items: center; - justify-content: center; - background-color: $color-dashboard; - border-radius: $br3; - - svg { - width: 15px; - height: 15px; - } - - &.unread { - background-color: $color-warning; - svg { - fill: #2e3434; - } - } - - &.open { - background-color: $color-black; - svg { - fill: $color-primary; - } - } + button { + cursor: pointer; + background: none; + border: none; } +} - .dropdown { - width: 280px; - bottom: 35px; - left: 0px; +.thread-groups { + height: calc(100% - $s-32); + overflow-y: scroll; + max-height: $s-440; + overflow: auto; + + hr { + background-color: $df-primary; + border: 0; + height: $s-1; + margin: 0; } +} - .header { - display: flex; - height: 40px; - align-items: center; - padding: 0px 11px; - - h3 { - font-weight: $fw400; - color: $color-black; - font-size: $fs14; - // line-height: $lh-128; // Original value was $fs18 => 1.125rem = 18px; 18px/14px = 128.571428571% => $lh-128 (rounded) - flex-grow: 1; - } - - .close { - display: flex; - align-items: center; - } - - svg { - width: 15px; - height: 15px; - transform: rotate(45deg); - } - } - - .thread-groups { - max-height: calc(30rem - 40px); - overflow: auto; - - hr { - background-color: $color-gray-10; - } - } - - .thread-group .section-title { - color: $color-black; - } - - .comment { - .author .name .fullname { - color: $color-gray-40; - } - .content { - color: $color-black; - } - } +.thread-group { + display: flex; + flex-direction: column; + font-size: $fs-12; } .thread-groups-placeholder { align-items: center; display: flex; flex-direction: column; - font-size: $fs12; - padding: $size-5; + font-size: $fs-12; + padding: $s-24; text-align: center; svg { - fill: $color-gray-20; - height: 24px; - margin-bottom: $size-5; - width: 24px; + fill: $df-secondary; + height: $s-24; + margin-bottom: $s-24; + width: $s-24; } } -.dashboard-comments-section { - border-color: transparent; - border-radius: 8px; - background-color: $db-primary; - height: 32px; - width: 32px; +.button { + display: flex; + align-items: center; + justify-content: center; + border-radius: $br-8; + height: $s-32; + width: $s-32; - .button { - border-radius: 8px; - background-color: $db-primary; - height: 32px; - width: 32px; + svg { + width: $s-16; + height: $s-16; + fill: $df-secondary; + } + + &.unread svg, + &.open svg { + fill: $da-tertiary; + } + + &:hover { + background-color: $db-cuaternary; svg { - fill: $df-secondary; - } - - &:hover { - background-color: $db-cuaternary; - - svg { - fill: $da-primary; - } + fill: $da-primary; + } + } +} + +.dropdown { + background-color: $db-tertiary; + border-radius: $br-8; + border: $s-1 solid transparent; + bottom: $s-4; + box-shadow: 0px 2px 8px rgba(0, 0, 0, 0.25); + height: 40vh; + max-height: $s-480; + min-height: $s-200; + position: absolute; + width: 100%; + z-index: 12; + + hr { + margin: 0; + border-color: $df-secondary; + } +} + +.header { + display: flex; + height: $s-40; + align-items: center; + padding: 0 $s-12; + + h3 { + color: $df-secondary; + font-size: $fs-11; + line-height: 1.28; + flex-grow: 1; + text-transform: uppercase; + } + + .close { + display: flex; + align-items: center; + cursor: pointer; + svg { + width: $s-16; + height: $s-16; + transform: rotate(45deg); + fill: $df-secondary; } } } diff --git a/frontend/src/app/main/ui/dashboard/files.scss b/frontend/src/app/main/ui/dashboard/files.scss index 6e68a7bc9c..72b0485a54 100644 --- a/frontend/src/app/main/ui/dashboard/files.scss +++ b/frontend/src/app/main/ui/dashboard/files.scss @@ -1,237 +1,28 @@ -@import "common/dependencies/colors"; +// 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 -// FIXME: Mostly duplcated from projects.css - -$br3: 3px; -$fs14: 0.875rem; -$fs18: 1.125rem; -$fs22: 1.375rem; -$fw400: 400; -$fw600: 600; -$lh-088: 0.88; -$lh-115: 1.15; // original $title-lh-sm -$size-1: 0.25rem; -$size-2: 0.5rem; -$size-4: 1rem; -$size-5: 1.5rem; -$size-6: 2rem; +@use "common/refactor/common-refactor.scss" as *; +@use "common/refactor/common-dashboard"; .dashboard-container { - background-color: $color-dashboard; flex: 1 0 0; - margin-right: $size-4; + margin-right: $s-16; overflow-y: auto; width: 100%; + border-top: $s-1 solid $db-cuaternary; + &.dashboard-projects { user-select: none; } - &.no-bg { - background-color: transparent; - } &.dashboard-shared { - width: calc(100vw - 320px); - margin-right: 50px; + width: calc(100vw - $s-320); + margin-right: $s-52; } &.search { - margin-top: 10px; - } -} - -.dashboard-header { - display: flex; - align-items: center; - justify-content: space-between; - background-color: $color-white; - height: 63px; - padding: $size-1 $size-4 $size-1 $size-2; - position: relative; - z-index: 10; - user-select: none; - &.team { - display: grid; - grid-template-columns: 20% 1fr 20%; - } - - .element-name { - margin-right: $size-2; - } - - .btn-secondary { - flex-shrink: 0; - z-index: 10; - height: 32px; - } - - svg { - fill: $color-black; - height: 14px; - margin-right: $size-1; - width: 14px; - } - - nav { - display: flex; - align-items: flex-end; - justify-content: center; - z-index: 1; - - ul { - display: flex; - font-size: $fs14; - justify-content: center; - margin: 0; - } - - li { - a { - display: flex; - align-items: center; - flex-basis: 140px; - border-bottom: 3px solid transparent; - color: $color-gray-30; - height: 40px; - padding: $size-1 $size-5; - font-weight: $fw400; - &:hover { - color: $color-black; - text-decoration: none; - } - } - - &.active { - a { - color: $color-black; - border-color: $color-primary; - } - } - } - } - - .dashboard-title { - display: flex; - align-items: center; - margin-left: 13px; - - h1 { - color: $color-black; - display: flex; - flex-shrink: 0; - font-size: $fs22; - font-weight: $fw600; - z-index: 10; - user-select: all; - } - - .context-menu.is-open { - margin-top: 10px; - } - } - - .icon { - display: flex; - align-items: center; - cursor: pointer; - margin-left: $size-2; - z-index: 10; - - svg { - fill: $color-gray-40; - width: 15px; - height: 15px; - - &:hover { - fill: $color-primary-dark; - } - } - } - - .dashboard-buttons { - display: flex; - justify-content: flex-end; - align-items: center; - } - - .dashboard-header-actions { - display: flex; - } - - .pin-icon { - margin: 0 $size-2 0 $size-5; - background-color: transparent; - border: none; - svg { - fill: $color-gray-20; - } - - &.active { - svg { - fill: $color-gray-50; - } - } - } -} - -.dashboard-header { - background-color: transparent; - .dashboard-title { - h1 { - color: $df-primary; - font-size: 24px; - font-weight: 400; - width: 100%; - text-overflow: ellipsis; - overflow: hidden; - white-space: nowrap; - display: block; - max-width: 700px; - } - } - .icon { - svg { - fill: $df-secondary; - } - } - - // Settings sub-menu - .dashboard-header-options { - li { - a { - font-size: 16px; - color: $df-secondary; - border-color: transparent; - &:hover { - color: $df-primary; - } - } - &.active { - a { - color: $df-primary; - } - } - } - } -} - -.btn-secondary { - background-color: $db-tertiary; - text-transform: uppercase; - border: none; - color: $df-primary; - border-radius: 8px; - - font-size: 0.75rem; - padding: 0 1rem; - cursor: pointer; - display: flex; - justify-content: center; - align-items: center; - - &:hover { - background-color: $db-cuaternary; - color: $da-primary; - svg { - fill: $da-primary; - } + margin-top: $s-12; } } diff --git a/frontend/src/app/main/ui/dashboard/fonts.cljs b/frontend/src/app/main/ui/dashboard/fonts.cljs index e8551a5aed..cedfdaf560 100644 --- a/frontend/src/app/main/ui/dashboard/fonts.cljs +++ b/frontend/src/app/main/ui/dashboard/fonts.cljs @@ -122,6 +122,17 @@ [:h2 (tr "labels.upload-custom-fonts")] [:& i18n/tr-html {:label "dashboard.fonts.hero-text1"}] + [:button + {:class (stl/css :btn-primary) + :on-click on-click + :tab-index "0"} + [:span (tr "labels.add-custom-font")] + [:& file-uploader {:input-id "font-upload" + :accept cm/str-font-types + :multi true + :ref input-ref + :on-selected on-selected}]] + [:div {:class (stl/css :banner)} [:div {:class (stl/css :icon)} i/msg-info] [:div {:class (stl/css :content)} @@ -135,16 +146,7 @@ [:& i18n/tr-html {:tag-name "span" :label "dashboard.fonts.warning-text"}]]])] - [:button - {:class (stl/css :btn-primary) - :on-click on-click - :tab-index "0"} - [:span (tr "labels.add-custom-font")] - [:& file-uploader {:input-id "font-upload" - :accept cm/str-font-types - :multi true - :ref input-ref - :on-selected on-selected}]]] + ] [:* (when (some? (vals @fonts)) diff --git a/frontend/src/app/main/ui/dashboard/fonts.scss b/frontend/src/app/main/ui/dashboard/fonts.scss index 5273c0a9b9..7265fa51cd 100644 --- a/frontend/src/app/main/ui/dashboard/fonts.scss +++ b/frontend/src/app/main/ui/dashboard/fonts.scss @@ -1,621 +1,316 @@ -@import "common/dependencies/colors"; +// 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 -$br3: 3px; -$fs12: 0.75rem; -$fs14: 0.875rem; -$fs14: 0.875rem; -$fs18: 1.125rem; -$fs22: 1.375rem; -$fw400: 400; -$fw600: 600; -$lh-088: 0.88; -$lh-115: 1.15; // original $title-lh-sm -$size-1: 0.25rem; -$size-2: 0.5rem; -$size-4: 1rem; -$size-5: 1.5rem; -$size-6: 2rem; - -.dashboard-header { - display: flex; - align-items: center; - justify-content: space-between; - background-color: $color-white; - height: 63px; - padding: $size-1 $size-4 $size-1 $size-2; - position: relative; - z-index: 10; - user-select: none; - &.team { - display: grid; - grid-template-columns: 20% 1fr 20%; - } - - .element-name { - margin-right: $size-2; - } - - .btn-secondary { - flex-shrink: 0; - z-index: 10; - height: 32px; - } - - svg { - fill: $color-black; - height: 14px; - margin-right: $size-1; - width: 14px; - } - - nav { - display: flex; - align-items: flex-end; - justify-content: center; - z-index: 1; - - ul { - display: flex; - font-size: $fs14; - justify-content: center; - margin: 0; - } - - li { - a { - display: flex; - align-items: center; - flex-basis: 140px; - border-bottom: 3px solid transparent; - color: $color-gray-30; - height: 40px; - padding: $size-1 $size-5; - font-weight: $fw400; - &:hover { - color: $color-black; - text-decoration: none; - } - } - - &.active { - a { - color: $color-black; - border-color: $color-primary; - } - } - } - } - - .dashboard-title { - display: flex; - align-items: center; - margin-left: 13px; - - h1 { - color: $color-black; - display: flex; - flex-shrink: 0; - font-size: $fs22; - font-weight: $fw600; - z-index: 10; - user-select: all; - } - - .context-menu.is-open { - margin-top: 10px; - } - } - - .icon { - display: flex; - align-items: center; - cursor: pointer; - margin-left: $size-2; - z-index: 10; - - svg { - fill: $color-gray-40; - width: 15px; - height: 15px; - - &:hover { - fill: $color-primary-dark; - } - } - } - - .dashboard-buttons { - display: flex; - justify-content: flex-end; - align-items: center; - } - - .dashboard-header-actions { - display: flex; - } - - .pin-icon { - margin: 0 $size-2 0 $size-5; - background-color: transparent; - border: none; - svg { - fill: $color-gray-20; - } - - &.active { - svg { - fill: $color-gray-50; - } - } - } -} - -.dashboard-header { - background-color: transparent; - .dashboard-title { - h1 { - color: $df-primary; - font-size: 24px; - font-weight: 400; - width: 100%; - text-overflow: ellipsis; - overflow: hidden; - white-space: nowrap; - display: block; - max-width: 700px; - } - } - .icon { - svg { - fill: $df-secondary; - } - } - - // Settings sub-menu - .dashboard-header-options { - li { - a { - font-size: 16px; - color: $df-secondary; - border-color: transparent; - &:hover { - color: $df-primary; - } - } - &.active { - a { - color: $df-primary; - } - } - } - } -} +@use "common/refactor/common-refactor.scss" as *; +@use "common/refactor/common-dashboard"; .dashboard-fonts { + border-top: $s-1 solid $db-cuaternary; display: flex; flex-direction: column; - align-items: center; + padding-left: $s-120; + overflow-y: auto; + padding-bottom: $s-120; +} - .dashboard-installed-fonts { - max-width: 1000px; - width: 100%; - display: flex; - margin-top: $size-5; - flex-direction: column; +.dashboard-installed-fonts { + max-width: $s-1000; + width: 100%; + display: flex; + margin-top: $s-24; + flex-direction: column; - h3 { - font-size: $fs14; - color: $color-gray-30; - margin: $size-1; - } - - .font-item { - color: $color-black; - } - } - - .installed-fonts-header { - color: $color-gray-40; - display: flex; - height: 40px; - font-size: $fs12; - background-color: $color-white; - align-items: center; - padding: 0px $size-5; - - > .family { - min-width: 200px; - width: 200px; - } - - > .variants { - padding-left: 12px; - } - - .search-input { - display: flex; - flex-grow: 1; - justify-content: flex-end; - - input { - font-size: $fs12; - border: 1px solid $color-gray-30; - border-radius: $br3; - width: 130px; - padding: $size-1; - margin: 0px; - } - } + h3 { + font-size: $fs-14; + color: $df-secondary; + margin: $s-4; } .font-item { - color: $color-gray-40; - font-size: $fs14; - background-color: $color-white; - display: flex; - max-width: 1000px; - width: 100%; - min-height: 97px; - align-items: center; - padding: $size-5; - justify-content: space-between; - - &:not(:first-child) { - border-top: 1px solid $color-gray-10; - } - - input { - border: 1px solid $color-gray-30; - border-radius: $br3; - margin: 0px; - padding: $size-2; - font-size: $fs12; - } - - > .family { - min-width: 200px; - width: 200px; - } - - > .filenames { - min-width: 200px; - } - - > .variants { - font-size: $fs14; - display: flex; - flex-wrap: wrap; - flex-grow: 1; - - .variant { - display: flex; - justify-content: space-between; - align-items: center; - padding: 8px 12px; - cursor: pointer; - - .icon { - display: flex; - height: 16px; - width: 16px; - margin-left: 6px; - align-items: center; - svg { - fill: transparent; - width: 12px; - height: 12px; - transform: rotate(45deg); - } - } - - &:hover { - .icon svg { - fill: $color-gray-30; - } - } - } - } - - .filenames { - display: flex; - flex-direction: column; - font-size: $fs12; - } - - .options { - display: flex; - justify-content: flex-end; - min-width: 180px; - - .icon { - width: $size-5; - cursor: pointer; - display: flex; - margin-left: 10px; - justify-content: center; - align-items: center; - &.failure { - margin-right: 10px; - svg { - fill: $color-warning; - } - } - svg { - width: 16px; - height: 16px; - fill: $df-secondary; - } - - &.close { - svg { - transform: rotate(45deg); - fill: $df-secondary; - } - } - } - } - } - - .dashboard-fonts-upload { - max-width: 1000px; - width: 100%; - display: flex; - flex-direction: column; - - .upload-button { - width: 100px; - } - - .btn-secondary { - margin-left: 10px; - } - } - - .dashboard-fonts-hero { - font-size: $fs14; - padding: $size-6; - background-color: $color-white; - margin-top: $size-6; - display: flex; - justify-content: space-between; - - .banner { - background-color: $color-info-lighter; - display: grid; - grid-template-columns: 40px 1fr; - &:not(:last-child) { - margin-bottom: 10px; - } - .icon { - display: flex; - align-items: flex-start; - justify-content: center; - padding-top: 10px; - background-color: $color-info; - svg { - fill: $color-white; - height: 20px; - width: 20px; - } - } - .content { - margin: 10px; - } - &.warning { - background-color: $color-warning-lighter; - .icon { - background-color: $color-warning; - } - } - } - - .desc { - h2 { - margin-bottom: $size-4; - color: $color-black; - } - width: 80%; - color: $color-gray-40; - } - - .btn-primary { - flex-shrink: 0; - } - } - - .fonts-placeholder { - display: flex; - flex-direction: column; - justify-content: center; - align-items: center; - max-width: 1000px; - width: 100%; - height: 161px; - - border: 1px dashed $color-gray-20; - margin-top: 16px; - - .icon { - svg { - fill: $color-gray-40; - width: 32px; - height: 32px; - } - } - - .label { - color: $color-gray-40; - font-size: $fs14; - } + color: $db-secondary; } } -.dashboard-fonts { - background-color: $db-primary; - border-top: 1px solid $db-cuaternary; +.installed-fonts-header { + align-items: center; + color: $df-secondary; + display: flex; + font-size: $fs-12; + height: $s-40; + padding-left: $s-24; + text-transform: uppercase; - .dashboard-fonts-hero { - background-color: transparent; - .desc { - width: 70%; - h2 { - color: $df-primary; - font-weight: 400; - } - p { - color: $df-secondary; - font-size: 14px; - } - .banner { - background-color: $db-primary; - border-radius: 8px; - border: 1px solid $db-cuaternary; - color: $df-primary; - font-size: 12px; - .content { - span { - a { - color: $da-primary; - } - } - } - .icon { - background-color: transparent; - svg { - fill: $df-secondary; - } - } - &.warning { - background-color: $db-cuaternary; - } - } - } + > .family { + min-width: $s-200; + width: $s-200; } - .installed-fonts-header { - background-color: transparent; - text-transform: uppercase; - color: $df-secondary; + > .variants { + padding-left: $s-12; } +} - .fonts-placeholder { - border: 1px solid $db-cuaternary; - border-radius: 8px; - .icon { - svg { - fill: $df-secondary; - } +.search-input { + display: flex; + flex-grow: 1; + justify-content: flex-end; + + input { + background-color: $db-tertiary; + border-color: transparent; + border-radius: $br-8; + border: $s-1 solid transparent; + color: $df-primary; + font-size: $fs-14; + height: $s-32; + margin: 0; + padding: 0 $s-8; + width: $s-152; + + &:focus { + outline: $s-1 solid $da-primary; } - .label { + &::placeholder { color: $df-secondary; } } - - .font-item { - background-color: $db-tertiary; - border-radius: 8px; - color: $df-secondary; - padding: 0.8rem 1.5rem; - min-height: auto; - margin-top: 4px; - &:not(:first-child) { - border: none; - } - .table-field { - color: $df-primary; - .variant { - background-color: $db-cuaternary; - border-radius: 8px; - margin-right: 4px; - padding-right: 4px; - } - } - } - - .font-item { - input { - background-color: $db-tertiary; - border-color: transparent; - border-radius: 8px; - color: $df-primary; - font-size: 14px; - &:focus { - outline: 1px solid $da-primary; - } - } - > .variants { - padding-left: 1rem; - } - } - - .installed-fonts-header { - padding-right: 0; - .search-input { - input { - background-color: $db-tertiary; - border-color: transparent; - border-radius: 8px; - color: $df-primary; - font-size: 14px; - height: 32px; - padding: 0 0.6rem; - width: 150px; - &:focus { - outline: 1px solid $da-primary; - } - &::placeholder { - color: $df-secondary; - } - } - } - } } -.btn-primary { - background-color: $da-tertiary; - border-radius: 8px; - color: $db-primary; - height: 32px; - text-transform: uppercase; - - appearance: none; +.font-item { align-items: center; - border: none; - cursor: pointer; - display: flex; - font-family: "worksans", sans-serif; - font-size: $fs12; - justify-content: center; - min-width: 25px; - padding: 0 1rem; - transition: all 0.4s; - text-decoration: none; - - &:hover { - background-color: darken($da-tertiary, 10%); - color: $db-primary; - } -} - -.btn-secondary { background-color: $db-tertiary; - text-transform: uppercase; - border: none; - color: $df-primary; - border-radius: 8px; - - font-size: 0.75rem; - padding: 0 1rem; - cursor: pointer; + border-radius: $br-4; + color: $df-secondary; display: flex; - justify-content: center; - align-items: center; + font-size: $fs-14; + justify-content: space-between; + margin-top: $s-4; + max-width: $s-1000; + padding: $s-12 $s-24; + width: 100%; - &:hover { - background-color: $db-cuaternary; - color: $da-primary; - svg { - fill: $da-primary; + input { + border: $s-1 solid transparent; + margin: 0; + padding: $s-8; + + background-color: $db-tertiary; + border-radius: $br-8; + color: $df-primary; + font-size: $fs-14; + + &:focus { + outline: $s-1 solid $da-primary; + } + } + + > .family { + min-width: $s-200; + width: $s-200; + } + + > .filenames { + min-width: $s-200; + } + + > .variants { + font-size: $fs-14; + display: flex; + flex-wrap: wrap; + flex-grow: 1; + padding-left: $s-16; + + .variant { + display: flex; + justify-content: space-between; + align-items: center; + padding: $s-8 $s-12; + cursor: pointer; + + .icon { + display: flex; + height: $s-16; + width: $s-16; + margin-left: $s-6; + align-items: center; + svg { + fill: transparent; + width: $s-12; + height: $s-12; + transform: rotate(45deg); + } + } + + &:hover { + .icon svg { + fill: $df-secondary; + } + } + } + } + + .table-field { + color: $df-primary; + .variant { + background-color: $db-cuaternary; + border-radius: $br-8; + margin-right: $s-4; + padding-right: $s-4; + } + } + + .filenames { + display: flex; + flex-direction: column; + font-size: $fs-12; + } + + .options { + display: flex; + justify-content: flex-end; + min-width: $s-180; + + .icon { + width: $s-24; + cursor: pointer; + display: flex; + margin-left: $s-12; + justify-content: center; + align-items: center; + &.failure { + margin-right: $s-12; + svg { + fill: var(--warning-color); + } + } + svg { + width: $s-16; + height: $s-16; + fill: $df-secondary; + } + + &.close { + svg { + transform: rotate(45deg); + fill: $df-secondary; + } + } } } } + +.dashboard-fonts-upload { + max-width: $s-1000; + width: 100%; + display: flex; + flex-direction: column; + + .upload-button { + width: $s-100; + } + + .btn-secondary { + margin-left: $s-12; + } +} + +.dashboard-fonts-hero { + font-size: $fs-14; + padding: $s-32 0; + margin-top: $s-80; + display: flex; + justify-content: space-between; + + .btn-primary { + height: $s-40; + width: 100%; + } + + .desc { + display: flex; + flex-direction: column; + gap: $s-24; + color: $db-secondary; + width: $s-500; + + h2 { + color: $df-primary; + font-weight: 400; + } + p { + color: $df-secondary; + font-size: $fs-16; + } + } + + .banner { + overflow: hidden; + display: grid; + grid-template-columns: $s-40 1fr; + + background-color: $db-primary; + border-radius: $br-12; + border: $s-1 solid $db-cuaternary; + color: $df-primary; + font-size: $fs-12; + + &:not(:last-child) { + margin-bottom: $s-12; + } + .icon { + display: flex; + align-items: flex-start; + justify-content: center; + padding-top: $s-12; + + svg { + fill: $df-secondary; + height: $s-20; + width: $s-20; + } + } + .content { + margin: $s-12; + a { + color: $da-primary; + } + } + &.warning { + background-color: $db-cuaternary; + .icon svg { + fill: var(--warning-color); + } + } + } + + .btn-primary { + flex-shrink: 0; + } +} + +.fonts-placeholder { + align-items: center; + border-radius: $br-8; + border: $s-1 solid $db-cuaternary; + display: flex; + flex-direction: column; + height: $s-160; + justify-content: center; + margin-top: $s-16; + max-width: $s-1000; + width: 100%; + + .icon svg { + fill: $df-secondary; + width: $s-32; + height: $s-32; + } + + .label { + color: $df-secondary; + font-size: $fs-14; + } +} diff --git a/frontend/src/app/main/ui/dashboard/grid.cljs b/frontend/src/app/main/ui/dashboard/grid.cljs index 61b58cf4ef..2241a7239c 100644 --- a/frontend/src/app/main/ui/dashboard/grid.cljs +++ b/frontend/src/app/main/ui/dashboard/grid.cljs @@ -313,11 +313,17 @@ [:span.date time]))) (defn create-counter-element - [_element file-count] - (let [counter-el (dom/create-element "div")] - (dom/set-property! counter-el "class" "drag-counter") - (dom/set-text! counter-el (str file-count)) - counter-el)) + [_element file-count new-css-system] + (if new-css-system + (let [counter-el (dom/create-element "div")] + (dom/set-property! counter-el "class" (stl/css :drag-counter)) + (dom/set-text! counter-el (str file-count)) + counter-el) + + (let [counter-el (dom/create-element "div")] + (dom/set-property! counter-el "class" "drag-counter") + (dom/set-text! counter-el (str file-count)) + counter-el))) (mf/defc grid-item {:wrap [mf/memo]} @@ -366,10 +372,12 @@ select-current? (not (contains? selected-files (:id file))) item-el (mf/ref-val node-ref) - counter-el (create-counter-element item-el - (if select-current? - 1 - (count selected-files)))] + counter-el (create-counter-element + item-el + (if select-current? + 1 + (count selected-files)) + new-css-system)] (when select-current? (st/emit! (dd/clear-selected-files)) (st/emit! (dd/toggle-file-select file))) @@ -829,5 +837,3 @@ {:dragging? @dragging? :limit limit :create-fn create-fn}])]))) - - diff --git a/frontend/src/app/main/ui/dashboard/grid.scss b/frontend/src/app/main/ui/dashboard/grid.scss index 8446762ca6..096ef69033 100644 --- a/frontend/src/app/main/ui/dashboard/grid.scss +++ b/frontend/src/app/main/ui/dashboard/grid.scss @@ -1,517 +1,375 @@ -@import "common/dependencies/colors"; +// 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 -$size-1: 0.25rem; -$size-2: 0.5rem; -$size-3: 0.75rem; -$size-4: 1rem; -$size-6: 2rem; -$fs12: 0.75rem; -$fs14: 0.875rem; -$fs18: 1.125rem; -$fw400: 400; -$fw500: 500; -$bp-max-1366: "(max-width: 1366px)"; -$br2: 2px; -$br3: 3px; -$br4: 4px; -$br5: 5px; -$lh-192: 1.92; +@import "refactor/common-refactor.scss"; .dashboard-grid { - font-size: $fs14; + font-size: $fs-14; height: 100%; - overflow: hidden; overflow-y: auto; - margin-bottom: 0; + overflow: hidden; +} - .grid-row { - display: grid; - width: 99%; - margin-left: 13px; +.grid-row { + display: grid; + width: 100%; + padding: 0 $s-12; +} + +.grid-item { + align-items: center; + cursor: pointer; + display: flex; + flex-direction: column; + flex: 1 0 $s-260; + height: $s-232; + margin: $s-12 $s-16 $s-16 $s-8; + position: relative; + text-align: center; + + a, + button { + width: 100%; + font-weight: $fw400; + } + button { + background-color: transparent; + border: none; } - .grid-item { - align-items: center; - cursor: pointer; - display: flex; - flex-direction: column; - flex: 1 0 260px; - height: 230px; - margin: $size-3 $size-4 $size-4 $size-2; - position: relative; - text-align: center; - a, - button { - width: 100%; - font-weight: $fw400; - } - button { - background-color: transparent; - border: none; - } - @media #{$bp-max-1366} { - height: 200px; - flex: 1 0 230px; - } - - &:hover { - .grid-item-th { - border: 2px solid $color-primary; - } - } - - .grid-item-th { - border-radius: $br3; - border: 2px solid lighten($color-gray-20, 15%); - text-align: initial; - - img { - object-fit: contain; - } - } - - &.dragged { - border-radius: $br3; - border: 2px solid lighten($color-gray-20, 15%); - text-align: initial; - max-height: 160px; - } - - &.placeholder { - min-width: 115px; - max-width: 115px; - - display: flex; - flex-direction: column; - justify-content: center; - - .placeholder-icon { - svg { - transform: rotate(-90deg); - width: 20px; - height: 20px; - fill: $color-gray-30; - } - } - - .placeholder-label { - font-size: $fs14; - } - } - - &.overlay { - border-radius: $br4; - border: 2px solid $color-primary; - height: 100%; - opacity: 0; - pointer-events: none; - position: absolute; - width: 100%; - z-index: 1; - } - - &:hover .overlay { - display: block; - opacity: 1; - } - - &.small-item { - max-width: 12%; - min-width: 190px; - padding: $size-4; - justify-content: center; - } - - .grid-item-icon { - width: 90px; - height: 90px; - } - .info-wrapper { - display: grid; - grid-template-columns: 1fr auto; - } - - .item-info { - display: grid; - padding: $size-2; - text-align: left; - width: 100%; - font-size: $fs12; - - h3 { - border: 1px solid transparent; - color: $color-gray-60; - font-size: $fs14; - font-weight: $fw500; - overflow: hidden; - padding: 0; - height: 27px; - padding-right: $size-2; - text-overflow: ellipsis; - width: 100%; - white-space: nowrap; - line-height: $lh-192; // Original value was 27px; 27px/14px = 192.857142857% => $lh-192 (rounded) - max-width: 260px; - @media #{$bp-max-1366} { - max-width: 230px; - } - } - - span.date { - color: $color-gray-30; - overflow: hidden; - text-overflow: ellipsis; - width: 100%; - white-space: nowrap; - max-width: 260px; - &::first-letter { - text-transform: capitalize; - } - @media #{$bp-max-1366} { - max-width: 230px; - } - } - - .edit-wrapper { - .element-title { - padding: 0px; - height: 25px; - color: $color-gray-60; - font-size: $fs14; - font-weight: $fw400; - } - } - } - - .item-badge { - background-color: $color-white; - border: 1px solid $color-gray-20; - border-radius: $br2; - position: absolute; - top: $size-2; - right: $size-2; - height: 32px; - width: 32px; - display: flex; - align-items: center; - justify-content: center; - - svg { - fill: $color-gray-30; - height: 16px; - width: 16px; - } - } - - &.add-file { - border: 1px dashed $color-gray-20; - justify-content: center; - box-shadow: none; - - span { - color: $color-gray-60; - font-size: $fs14; - } - - &:hover { - background-color: $color-white; - border: 2px solid $color-primary; - } - } - - // PROJECTS, ELEMENTS & ICONS GRID - &.project-th { - background-color: $color-white; - - &:hover, - &:focus, - &:focus-within { - .project-th-actions { - opacity: 1; - } - a { - text-decoration: none; - } - } - - .selected { - .grid-item-th { - border: 2px solid $color-primary; - } - } - - .project-th-actions { - align-items: center; - opacity: 0; - display: flex; - right: 5px; - justify-content: center; - width: 30px; - height: 100%; - - span { - color: $color-black; - } - - .project-th-icon { - align-items: center; - display: flex; - margin-right: $size-2; - - &.menu { - margin-right: 0; - display: flex; - justify-content: center; - align-items: flex-end; - flex-direction: column; - width: 100%; - height: 30px; - margin-top: 20px; - - > svg { - fill: $color-gray-60; - margin-right: 0; - height: 18px; - width: 18px; - } - - &:hover, - &:focus { - > svg { - fill: $color-primary-dark; - } - } - } - } - } - - .project-th-actions.force-display { - opacity: 1; - } - } - - // IMAGES SECTION - &.images-th { - border: 1px dashed $color-gray-20; - border-bottom: 2px solid lighten($color-gray-20, 12%); - - &:hover { - border-color: $color-primary; - } - } - - .grid-item-image { - svg { - max-height: 100px; - max-width: 100px; - min-height: 40px; - min-width: 40px; - width: 8vw; - } - } - - .color-swatch { - border-top-left-radius: $br5; - border-top-right-radius: $br5; - height: 25%; - left: 0; - position: absolute; - top: 0; - width: 100%; - } - - .color-data { - color: $color-gray-30; - margin-top: 15px; - } - - .drag-counter { - position: absolute; - top: 5px; - left: 4px; - width: 32px; - height: 32px; - background-color: $color-primary; - border-radius: 50%; - color: $color-black; - font-size: $fs18; - display: flex; - justify-content: center; - align-items: center; - } + @media #{$bp-max-1366} { + height: $s-200; + flex: 1 0 $s-232; } .grid-item-th { - background-position: center; - background-size: auto 80%; - background-repeat: no-repeat; - border-top-left-radius: $br3; - border-top-right-radius: $br3; - height: 230px; - max-height: 160px; - overflow: hidden; - position: relative; + border-radius: $br-4; + text-align: initial; + + img { + object-fit: contain; + } + } + + &.dragged { + border-radius: $br-4; + border: $br-2 solid $da-primary; + text-align: initial; + max-height: $s-160; + } + + &.overlay { + border-radius: $br-4; + border: $s-2 solid $da-tertiary; + height: 100%; + opacity: 0; + pointer-events: none; + position: absolute; width: 100%; + z-index: $z-index-1; + } - background-color: $color-canvas; - display: flex; - justify-content: center; - flex-direction: row; + &:hover .overlay { + display: block; + opacity: 1; + } - .img-th { - height: auto; + .info-wrapper { + display: grid; + grid-template-columns: 1fr auto; + cursor: pointer; + } + + .item-info { + display: grid; + padding: $s-8; + text-align: left; + width: 100%; + font-size: $fs-12; + + h3 { + border: $s-1 solid transparent; + color: $df-primary; + font-size: $fs-16; + font-weight: $fw400; + height: $s-28; + line-height: 1.92; + max-width: $s-260; + overflow: hidden; + padding-right: $s-8; + padding: 0; + text-overflow: ellipsis; + white-space: nowrap; width: 100%; + + @media #{$bp-max-1366} { + max-width: $s-232; + } + } + + .date { + color: $df-secondary; + overflow: hidden; + text-overflow: ellipsis; + width: 100%; + white-space: nowrap; + max-width: $s-260; + &::first-letter { + text-transform: capitalize; + } + @media #{$bp-max-1366} { + max-width: $s-232; + } + } + } + + .item-badge { + background-color: $da-primary; + border: none; + border-radius: $br-4; + position: absolute; + top: $s-8; + right: $s-8; + height: $s-32; + width: $s-32; + display: flex; + align-items: center; + justify-content: center; + + svg { + fill: $db-secondary; + height: $s-16; + width: $s-16; + } + } + + &.add-file { + border: $s-1 dashed $df-secondary; + justify-content: center; + box-shadow: none; + + span { + color: $db-primary; + font-size: $fs-14; + } + + &:hover { + background-color: $df-primary; + border: $s-2 solid $da-tertiary; + } + } +} + +.drag-counter { + position: absolute; + top: $s-4; + left: $s-4; + width: $s-32; + height: $s-32; + background-color: $da-tertiary; + border-radius: 50%; + color: $db-secondary; + font-size: $fs-16; + display: flex; + justify-content: center; + align-items: center; +} + +// PROJECTS, ELEMENTS & ICONS GRID +.project-th { + background-color: transparent; + border-radius: $br-8; + padding-top: $s-6; + + &:hover, + &:focus, + &:focus-within { + background-color: $db-tertiary; + .project-th-actions { + opacity: 1; + } + a { + text-decoration: none; + } + } + + .selected { + .grid-item-th { + border: 2px solid $da-tertiary; + } + } +} + +.project-th-actions { + align-items: center; + display: flex; + height: 100%; + justify-content: center; + opacity: 0; + right: $s-6; + width: $s-32; + + span { + color: $db-secondary; + } + + .project-th-icon { + align-items: center; + display: flex; + margin-right: $s-8; + margin-top: 0; + + &.menu { + align-items: flex-end; + display: flex; + flex-direction: column; + height: $s-32; + justify-content: center; + margin-right: 0; + margin-top: $s-20; + width: 100%; + + > svg { + fill: $df-secondary; + margin-right: 0; + height: $s-16; + width: $s-16; + } + + &:hover, + &:focus { + > svg { + fill: $da-tertiary; + } + } + } + } +} + +.project-th-actions.force-display { + opacity: 1; +} + +.grid-item-th { + border-radius: $br-4; + cursor: pointer; + + background-position: center; + background-size: auto 80%; + background-repeat: no-repeat; + + height: $s-232; + max-height: $s-160; + overflow: hidden; + position: relative; + width: 100%; + + background-color: var(--canvas-color); + display: flex; + justify-content: center; + flex-direction: row; + + .img-th { + height: auto; + width: 100%; + } + + svg { + height: 100%; + width: 100%; + } + + svg#loader-pencil { + fill: $db-cuaternary; + } +} + +// LIBRARY VIEW +.library { + height: $s-580; +} + +.grid-item.project-th.library { + height: $s-612; + width: $s-300; +} + +.grid-item-th.library { + background-color: $db-tertiary; + flex-direction: column; + height: 90%; + justify-content: flex-start; + max-height: 550px; + padding: $s-32; + + .asset-section { + font-size: $fs-12; + color: $df-secondary; + + &:not(:first-child) { + margin-top: $s-16; + } + } + + .asset-title { + display: flex; + font-size: $fs-12; + text-transform: uppercase; + + .num-assets { + color: $df-secondary; + } + } + + .asset-list-item { + align-items: center; + border-radius: $br-4; + border: $s-1 solid transparent; + color: $df-primary; + display: flex; + font-size: $fs-12; + margin-top: $s-4; + padding: $s-2; + position: relative; + + .name-block { + color: $df-secondary; + width: calc(100% - $s-24 - $s-8); + } + + .item-name { + display: block; + overflow: hidden; + text-overflow: ellipsis; + white-space: nowrap; } svg { - height: 100%; - width: 100%; + background-color: var(--canvas-color); + border-radius: $br-4; + border: $s-2 solid transparent; + height: $s-24; + margin-right: $s-8; + width: $s-24; } - svg#loader-pencil { - fill: $color-gray-20; - } - } - - // LIBRARY VIEW - .grid-item { - .library { - height: 580px; + .color-name { + color: $df-primary; } - &.project-th.library { - height: 610px; - width: 300px; + .color-value { + color: $df-secondary; + margin-left: $s-4; + text-transform: uppercase; } - .grid-item-th.library { - background-color: $color-gray-50; - flex-direction: column; - height: 90%; - justify-content: flex-start; - max-height: 550px; - padding: $size-6; - - .asset-section { - font-size: $fs12; - color: $color-gray-20; - - &:not(:first-child) { - margin-top: $size-4; - } - } - - .asset-title { - display: flex; - font-size: $fs12; - text-transform: uppercase; - - & .num-assets { - color: $color-gray-30; - } - } - - .asset-list-item { - display: flex; - align-items: center; - border: 1px solid transparent; - border-radius: $br3; - margin-top: $size-1; - padding: 2px; - font-size: $fs12; - color: $color-white; - position: relative; - - & .name-block { - color: $color-gray-20; - width: calc(100% - 24px - #{$size-2}); - } - - & .item-name { - overflow: hidden; - text-overflow: ellipsis; - white-space: nowrap; - display: block; - } - - & svg { - background-color: $color-canvas; - border-radius: $br4; - border: 2px solid transparent; - height: 24px; - width: 24px; - margin-right: $size-2; - } - - & .color-name { - color: $color-white; - } - - & .color-value { - margin-left: $size-1; - color: $color-gray-30; - text-transform: uppercase; - } - - & .typography-sample { - height: 20px; - margin-right: $size-1; - width: 20px; - } - } - } - } -} - -.dashboard-grid { - .grid-item { - &.project-th { - background-color: transparent; - border-radius: 8px; - padding-top: 0.3rem; - .info-wrapper { - cursor: pointer; - .item-info { - h3 { - color: $df-primary; - font-size: 16px; - font-weight: 400; - } - } - .date { - color: $df-secondary; - } - .project-th-actions { - .project-th-icon { - margin-top: 0; - .icon-actions { - fill: $df-secondary; - } - } - } - } - - &:hover { - background-color: $db-tertiary; - .grid-item-th { - border: none; - } - } - } - - .grid-item-th { - border-radius: 4px; - border: none; - cursor: pointer; - } - - .item-badge { - background-color: $da-primary; - border: none; - border-radius: 4px; - svg { - fill: $db-secondary; - } + .typography-sample { + height: $s-20; + margin-right: $s-4; + width: $s-20; } } } diff --git a/frontend/src/app/main/ui/dashboard/inline_edition.cljs b/frontend/src/app/main/ui/dashboard/inline_edition.cljs index 3011ebdd5c..00d269066d 100644 --- a/frontend/src/app/main/ui/dashboard/inline_edition.cljs +++ b/frontend/src/app/main/ui/dashboard/inline_edition.cljs @@ -84,4 +84,3 @@ :on-blur on-blur}] [:span.close {:on-click on-cancel} i/close]]))) - diff --git a/frontend/src/app/main/ui/dashboard/inline_edition.scss b/frontend/src/app/main/ui/dashboard/inline_edition.scss index e69de29bb2..8abb170cb0 100644 --- a/frontend/src/app/main/ui/dashboard/inline_edition.scss +++ b/frontend/src/app/main/ui/dashboard/inline_edition.scss @@ -0,0 +1,53 @@ +// 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 *; + +.edit-wrapper { + border-radius: $br-4; + display: flex; + padding-right: $s-24; + position: relative; + margin-right: $s-24; + + input.element-title { + background-color: $db-primary; + border-radius: $br-8; + color: $df-primary; + font-size: $fs-16; + height: $s-32; + margin: 0; + border: none; + padding: $s-6; + width: 100%; + + &:focus-visible { + border: $s-1 solid $da-primary; + outline: none; + } + } + + .close { + cursor: pointer; + position: absolute; + + top: $s-1; + right: calc(-1 * $s-8); + + svg { + fill: $df-secondary; + height: $s-16; + transform: rotate(45deg) translateY(7px); + width: $s-16; + margin: 0; + } + &:hover { + svg { + fill: var(--warning-color); + } + } + } +} diff --git a/frontend/src/app/main/ui/dashboard/libraries.scss b/frontend/src/app/main/ui/dashboard/libraries.scss index 443f1b6364..72b0485a54 100644 --- a/frontend/src/app/main/ui/dashboard/libraries.scss +++ b/frontend/src/app/main/ui/dashboard/libraries.scss @@ -1,752 +1,28 @@ -@import "common/dependencies/colors"; +// 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 -// FIXME: Mostly duplcated from projects.css - -$br3: 3px; -$fs14: 0.875rem; -$fs18: 1.125rem; -$fs22: 1.375rem; -$fw400: 400; -$fw600: 600; -$lh-088: 0.88; -$lh-115: 1.15; // original $title-lh-sm -$size-1: 0.25rem; -$size-2: 0.5rem; -$size-4: 1rem; -$size-5: 1.5rem; -$size-6: 2rem; - -.dashboard-header { - display: flex; - align-items: center; - justify-content: space-between; - background-color: $color-white; - height: 63px; - padding: $size-1 $size-4 $size-1 $size-2; - position: relative; - z-index: 10; - user-select: none; - &.team { - display: grid; - grid-template-columns: 20% 1fr 20%; - } - - .element-name { - margin-right: $size-2; - } - - .btn-secondary { - flex-shrink: 0; - z-index: 10; - height: 32px; - svg { - height: 16px; - width: 16px; - } - } - - svg { - fill: $color-black; - height: 14px; - margin-right: $size-1; - width: 14px; - } - - nav { - display: flex; - align-items: flex-end; - justify-content: center; - z-index: 1; - - ul { - display: flex; - font-size: $fs14; - justify-content: center; - margin: 0; - } - - li { - a { - display: flex; - align-items: center; - flex-basis: 140px; - border-bottom: 3px solid transparent; - color: $color-gray-30; - height: 40px; - padding: $size-1 $size-5; - font-weight: $fw400; - &:hover { - color: $color-black; - text-decoration: none; - } - } - - &.active { - a { - color: $color-black; - border-color: $color-primary; - } - } - } - } - - .dashboard-title { - display: flex; - align-items: center; - margin-left: 13px; - - h1 { - color: $color-black; - display: flex; - flex-shrink: 0; - font-size: $fs22; - font-weight: $fw600; - z-index: 10; - user-select: all; - } - - .context-menu.is-open { - margin-top: 10px; - } - } - - .icon { - display: flex; - align-items: center; - cursor: pointer; - margin-left: $size-2; - z-index: 10; - - svg { - fill: $color-gray-40; - width: 15px; - height: 15px; - - &:hover { - fill: $color-primary-dark; - } - } - } - - .dashboard-buttons { - display: flex; - justify-content: flex-end; - align-items: center; - } - - .dashboard-header-actions { - display: flex; - } - - .pin-icon { - margin: 0 $size-2 0 $size-5; - background-color: transparent; - border: none; - svg { - fill: $color-gray-20; - } - - &.active { - svg { - fill: $color-gray-50; - } - } - } -} - -.dashboard-header { - background-color: transparent; - .dashboard-title { - h1 { - color: $df-primary; - font-size: 24px; - font-weight: 400; - width: 100%; - text-overflow: ellipsis; - overflow: hidden; - white-space: nowrap; - display: block; - max-width: 700px; - } - } - .icon { - svg { - fill: $df-secondary; - } - } - - // Settings sub-menu - .dashboard-header-options { - li { - a { - font-size: 16px; - color: $df-secondary; - border-color: transparent; - &:hover { - color: $df-primary; - } - } - &.active { - a { - color: $df-primary; - } - } - } - } -} +@use "common/refactor/common-refactor.scss" as *; +@use "common/refactor/common-dashboard"; .dashboard-container { - background-color: $color-dashboard; flex: 1 0 0; - margin-right: $size-4; + margin-right: $s-16; overflow-y: auto; width: 100%; + border-top: $s-1 solid $db-cuaternary; + &.dashboard-projects { user-select: none; } - &.no-bg { - background-color: transparent; - } &.dashboard-shared { - width: calc(100vw - 320px); - margin-right: 50px; + width: calc(100vw - $s-320); + margin-right: $s-52; } &.search { - margin-top: 10px; - } -} - -.dashboard-container { - background-color: transparent; - border-top: 1px solid $db-cuaternary; - - .dashboard-settings { - a { - color: $df-secondary; - } - .form-container { - width: 800px; - margin: 80px auto auto 120px; - form { - width: 468px; - .fields-row { - .custom-input, - .custom-select { - flex-direction: column-reverse; - label { - position: relative; - text-transform: uppercase; - color: $df-primary; - font-size: 11px; - margin-bottom: 12px; - margin-left: -4px; - } - input, - select { - background-color: $db-tertiary; - border-radius: 8px; - border-color: transparent; - color: $df-primary; - padding: 0 15px; - &:focus { - outline: 1px solid $da-primary; - } - ::placeholder { - color: $df-secondary; - } - } - .help-icon { - bottom: 12px; - top: auto; - svg { - fill: $df-secondary; - } - } - &.disabled { - input { - background-color: $db-primary; - border-color: $db-cuaternary; - color: $df-secondary; - } - } - .input-container { - background-color: $db-tertiary; - border-radius: 8px; - border-color: transparent; - margin-top: 22px; - .main-content { - label { - position: absolute; - top: -24px; - } - span { - color: $df-primary; - } - } - &:focus { - border: 1px solid $da-primary; - } - } - textarea { - border-radius: 8px; - padding: 12px 14px; - background-color: $db-tertiary; - color: $df-primary; - border: none; - &:focus { - outline: 1px solid $da-primary; - } - } - } - } - .field-title { - color: $df-primary; - } - .field-title:not(:first-child) { - margin-top: 64px; - } - - .field-text { - color: $df-secondary; - } - button, - .btn-secondary { - width: 100%; - font-size: 11px; - text-transform: uppercase; - background-color: $db-tertiary; - color: $df-primary; - &:hover { - color: $da-primary; - background-color: $db-cuaternary; - } - } - hr { - display: none; - } - } - .links { - margin-top: 12px; - } - } - } - - //Access tokens - .dashboard-access-tokens { - width: 800px; - margin-left: 120px; - margin-top: 80px; - .access-tokens-hero-container { - background-color: transparent; - .access-tokens-hero { - width: 468px; - flex-direction: column; - gap: 32px; - background-color: transparent; - margin: 0; - padding: 0; - .desc { - background-color: transparent; - width: 100%; - h2 { - color: $df-primary; - font-size: 24px; - font-weight: regular; - margin-bottom: 32px; - } - p { - color: $df-secondary; - margin-bottom: 0; - font-size: 14px; - } - } - button { - width: 100%; - font-size: 11px; - text-transform: uppercase; - background-color: $db-tertiary; - color: $df-primary; - &:hover { - color: $da-primary; - background-color: $db-cuaternary; - } - } - } - } - .dashboard-table { - width: 800px; - .table-rows { - padding-top: 0; - .table-row { - font-size: 14px; - min-height: 40px; - height: fit-content; - .name { - color: $df-primary; - max-width: 480px; - overflow: hidden; - text-overflow: ellipsis; - display: -webkit-box; - -webkit-line-clamp: 2; - -webkit-box-orient: vertical; - } - .expiration-date { - color: $df-secondary; - } - } - } - } - .access-tokens-empty { - width: 468px; - border: 1px solid $db-cuaternary; - border-radius: 8px; - margin-top: 32px; - font-size: 14px; - background-color: transparent; - color: $df-secondary; - } - } - - // Team webhooks - &.dashboard-team-webhooks { - width: 800px; - margin-left: 120px; - margin-top: 80px; - border: none; - align-items: flex-start; - .webhooks-hero-container { - width: 468px; - background-color: transparent; - .webhooks-hero { - width: 468px; - flex-direction: column; - gap: 32px; - background-color: transparent; - margin: 0; - padding: 0; - .desc { - background-color: transparent; - width: 100%; - h2 { - color: $df-primary; - font-size: 24px; - font-weight: regular; - margin-bottom: 32px; - } - p { - color: $df-secondary; - margin-bottom: 0; - font-size: 14px; - } - } - .btn-primary { - width: 100%; - font-size: 11px; - text-transform: uppercase; - background-color: $db-tertiary; - color: $df-primary; - &:hover { - color: $da-primary; - background-color: $db-cuaternary; - } - } - } - } - .dashboard-table { - width: 800px; - .table-rows { - padding-top: 0; - .table-row { - font-size: 14px; - min-height: 40px; - height: fit-content; - .name { - color: $df-primary; - max-width: 480px; - } - .expiration-date { - color: $df-secondary; - } - } - } - } - .webhooks-empty { - width: 468px; - border: 1px solid $db-cuaternary; - border-radius: 8px; - margin-top: 32px; - font-size: 14px; - background-color: transparent; - color: $df-secondary; - } - } - - // Members section - .dashboard-table { - .table-header { - background-color: transparent; - color: $df-secondary; - font-size: 12px; - text-transform: uppercase; - } - .table-rows { - .table-row { - background-color: $db-tertiary; - border-radius: 8px; - color: $df-primary; - .rol-selector { - background-color: $db-cuaternary; - border-color: transparent; - border-radius: 8px; - } - } - } - .member-info { - .member-name .you, - .member-email { - color: $df-secondary; - } - } - .status-badge { - border-radius: 8px; - color: $db-primary; - text-transform: uppercase; - } - .empty-invitations { - border: 1px solid $db-cuaternary; - border-radius: 8px; - color: $df-secondary; - } - } - .actions-dropdown, - .options-dropdown { - background-color: $db-tertiary; - border: 1px solid $db-cuaternary; - border-radius: 8px; - min-width: 252px; - - .separator { - border-color: transparent; - margin-top: 10px; - } - - li { - border-radius: 8px; - height: 40px; - margin: 5px; - color: $df-primary; - - &:hover { - background-color: $db-cuaternary; - } - } - - &.options-dropdown { - li { - color: $df-primary; - &.warning { - color: $color-danger; - } - } - } - } -} - -.dashboard-project-row { - margin-bottom: $size-5; - position: relative; - - .project { - align-items: center; - background: $color-white; - border-radius: $br3; - display: flex; - flex-direction: row; - justify-content: space-between; - align-items: center; - margin-top: $size-4; - padding: $size-2 $size-2 $size-2 $size-4; - width: 99%; - max-height: 40px; - gap: $size-2; - .project-name-wrapper { - display: flex; - align-items: center; - justify-content: flex-start; - min-height: 32px; - margin-left: $size-2; - } - .show-more { - align-items: center; - color: $color-gray-30; - display: flex; - font-size: $fs14; - justify-content: space-between; - cursor: pointer; - background-color: transparent; - border: none; - .placeholder-icon { - transform: rotate(-90deg); - margin-left: 10px; - svg { - height: 14px; - width: 14px; - fill: $color-gray-30; - } - } - &:hover { - color: $color-primary-dark; - svg { - fill: $color-primary-dark; - } - } - } - - .btn-secondary { - border: none; - padding: $size-2; - } - - h2 { - cursor: pointer; - font-size: $fs18; - line-height: $lh-088; // Original value was 1rem = 16px; 16px/18px = 88.88888% => $lh-088 - font-weight: $fw600; - color: $color-black; - margin-right: $size-1; - } - - .edit-wrapper { - margin-right: $size-4; - } - - .info { - font-size: $fs14; - line-height: $lh-115; // Original value was 1rem = 16px; 16px/14px = 114.285714286% => $lh-115 (rounded) - font-weight: $fw400; - color: $color-gray-60; - margin-left: 0.75rem; - @media (max-width: 760px) { - display: none; - } - } - - .project-actions { - display: flex; - opacity: 1; - margin-left: $size-6; - - .btn-small { - height: 32px; - margin: 0 $size-2; - width: 32px; - svg { - height: 16px; - width: 16px; - } - } - } - - .pin-icon { - cursor: pointer; - display: flex; - align-items: center; - margin-right: 14px; - background-color: transparent; - border: none; - svg { - width: 15px; - height: 15px; - fill: $color-gray-20; - } - - &.active { - svg { - fill: $color-gray-50; - } - } - } - } - - &:hover, - &:focus, - &:focus-within { - .project-actions { - opacity: 1; - } - } - - .show-more { - align-items: center; - color: $color-gray-30; - display: flex; - font-size: $fs14; - justify-content: space-between; - cursor: pointer; - background-color: transparent; - border: none; - position: absolute; - top: 9px; - right: 53px; - .placeholder-icon { - transform: rotate(-90deg); - margin-left: 10px; - svg { - height: 14px; - width: 14px; - fill: $color-gray-30; - } - } - &:hover { - color: $color-primary-dark; - svg { - fill: $color-primary-dark; - } - } - } -} - -.dashboard-project-row .project { - background-color: transparent; - - h2 { - color: $df-primary; - font-weight: 400; - } - span, - .info { - color: $df-secondary; - } - .project-actions { - svg { - fill: $df-primary; - } - .pin-icon svg { - fill: $df-secondary; - } - } -} - -.btn-secondary { - background-color: $db-tertiary; - text-transform: uppercase; - border: none; - color: $df-primary; - border-radius: 8px; - - font-size: 0.75rem; - padding: 0 1rem; - cursor: pointer; - display: flex; - justify-content: center; - align-items: center; - - &:hover { - background-color: $db-cuaternary; - color: $da-primary; - svg { - fill: $da-primary; - } + margin-top: $s-12; } } diff --git a/frontend/src/app/main/ui/dashboard/placeholder.cljs b/frontend/src/app/main/ui/dashboard/placeholder.cljs index 4d4e5e25fb..6125dd1667 100644 --- a/frontend/src/app/main/ui/dashboard/placeholder.cljs +++ b/frontend/src/app/main/ui/dashboard/placeholder.cljs @@ -26,7 +26,7 @@ [:ul {:class (stl/css :grid-row :no-wrap) :style {:grid-template-columns (str "repeat(" limit ", 1fr)")}} - [:li {:class (stl/css :grid-item)}]] + [:li {:class (stl/css :grid-item :grid-empty-placeholder :dragged)}]] (= :libraries origin) [:div {:class (stl/css :grid-empty-placeholder :libs) @@ -39,7 +39,8 @@ {:class (stl/css :grid-empty-placeholder) :style {:grid-template-columns (str "repeat(" limit ", 1fr)")}} [:button {:class (stl/css :create-new) - :on-click on-click} (tr "dashboard.new-file")]]) + :on-click on-click} + i/add-refactor]]) ;; OLD (cond @@ -69,4 +70,3 @@ [:div.grid-empty-placeholder.loader [:div.icon i/loader] [:div.text (tr "dashboard.loading-files")]]))) - diff --git a/frontend/src/app/main/ui/dashboard/placeholder.scss b/frontend/src/app/main/ui/dashboard/placeholder.scss index 220f2152a0..5b0b45df82 100644 --- a/frontend/src/app/main/ui/dashboard/placeholder.scss +++ b/frontend/src/app/main/ui/dashboard/placeholder.scss @@ -1,25 +1,34 @@ -@import "common/dependencies/colors"; +// 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 -$br0: 0; -$br3: 3px; -$br12: 12px; -$fs16: 1rem; +@use "common/refactor/common-refactor.scss" as *; +@use "./grid.scss"; .grid-empty-placeholder { - border-radius: $br12; + border-radius: $br-12; display: grid; - background-color: rgba(227, 227, 227, 0.3); - padding: 13px; - margin-right: 13px; - height: 230px; + padding: $s-12; + margin-right: $s-12; + height: $s-232; + &.loader { justify-items: center; } + .icon { display: flex; align-items: center; justify-content: center; + svg { + width: $s-64; + height: $s-64; + fill: $df-secondary; + } } + &.libs { background-image: url(/images/ph-left.svg), url(/images/ph-right.svg); background-position: @@ -27,86 +36,57 @@ $fs16: 1rem; 85% top; background-repeat: no-repeat; align-items: center; - border: 1px dashed #b1b2b5; - border-radius: $br3; + border: $s-1 solid $db-cuaternary; + border-radius: $br-4; display: flex; flex-direction: column; - height: 200px; - margin: 1rem; - padding: 3rem; + height: $s-200; + margin: $s-16; + padding: $s-48; justify-content: center; + .text { + a { + color: $df-primary; + } p { - max-width: 360px; + max-width: $s-360; text-align: center; - font-size: $fs16; + font-size: $fs-16; } } } - .create-new { - background-color: white; - border: 2px solid $color-gray-10; - border-radius: $br3; - color: $color-black; - cursor: pointer; - height: 158px; - font-family: "worksans", sans-serif; - margin: 0.5rem; - &:hover { - border: 2px solid $color-primary; - } - } - - &.search { - align-items: center; - display: flex; - justify-content: center; - flex-direction: column; - height: 200px; - background: $color-white; - border: 1px dashed #e3e3e3; - border-radius: $br0; - } - - svg { - width: 36px; - height: 36px; - fill: $color-gray-20; - } - - .text { - margin-top: 10px; - color: $color-gray-30; - font-size: $fs16; - } -} - -.grid-empty-placeholder { - background-color: transparent; .create-new { background-color: $db-tertiary; - border-radius: 8px; - border: none; + border-radius: $br-8; color: $df-primary; + cursor: pointer; + height: $s-160; + margin: $s-8; text-transform: uppercase; + border: $s-2 solid transparent; + + svg { + width: $s-32; + height: $s-32; + stroke: $df-secondary; + } &:hover { + border: $s-2 solid $da-tertiary; background-color: $db-cuaternary; color: $da-primary; - } - } - &.search { - border: 1px solid $db-cuaternary; - border-radius: 8px; - .text { - color: $df-primary; - } - .icon { svg { - fill: $df-secondary; + stroke: $da-tertiary; } } } + + .text { + margin-top: $s-12; + color: $df-secondary; + font-size: $fs-16; + } } diff --git a/frontend/src/app/main/ui/dashboard/projects.cljs b/frontend/src/app/main/ui/dashboard/projects.cljs index d97dc9a16b..f84f160063 100644 --- a/frontend/src/app/main/ui/dashboard/projects.cljs +++ b/frontend/src/app/main/ui/dashboard/projects.cljs @@ -79,17 +79,20 @@ (if new-css-system [:div {:class (stl/css :team-hero)} - [:img {:src "images/deco-team-banner.png" :border "0" - :role "presentation"}] + [:div {:class (stl/css :img-wrapper)} + [:img {:src "images/deco-team-banner.png" + :border "0" + :role "presentation"}]] [:div {:class (stl/css :text)} [:div {:class (stl/css :title)} (tr "dasboard.team-hero.title")] [:div {:class (stl/css :info)} [:span (tr "dasboard.team-hero.text")] - [:a {:on-click on-nav-members-click} (tr "dasboard.team-hero.management")]]] - [:button - {:class (stl/css :btn-primary :invite) - :on-click on-invite-click} - (tr "onboarding.choice.team-up.invite-members")] + [:a {:on-click on-nav-members-click} (tr "dasboard.team-hero.management")]] + [:button + {:class (stl/css :btn-primary :invite) + :on-click on-invite-click} + (tr "onboarding.choice.team-up.invite-members")]] + [:button {:class (stl/css :close) :on-click on-close-click @@ -154,7 +157,7 @@ [:div {:class (stl/css :thumbnail)}] [:div {:class (stl/css :text)} [:h2 {:class (stl/css :title)} (tr "dasboard.tutorial-hero.title")] - [:p {:clas (stl/css :info)} (tr "dasboard.tutorial-hero.info")] + [:p {:class (stl/css :info)} (tr "dasboard.tutorial-hero.info")] [:button {:class (stl/css :btn-primary :action) :on-click download-tutorial} (case (:status @state) diff --git a/frontend/src/app/main/ui/dashboard/projects.scss b/frontend/src/app/main/ui/dashboard/projects.scss index ee5016a711..ff6d6cdbcf 100644 --- a/frontend/src/app/main/ui/dashboard/projects.scss +++ b/frontend/src/app/main/ui/dashboard/projects.scss @@ -1,634 +1,104 @@ -@import "common/dependencies/colors"; +// 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 -$br3: 3px; -$br8: 8px; -$br6: 6px; -$fs14: 0.875rem; -$fs18: 1.125rem; -$fs22: 1.375rem; -$fs24: 1.5rem; -$fw400: 400; -$fw600: 600; -$fw700: 700; -$lh-088: 0.88; -$lh-115: 1.15; // original $title-lh-sm -$size-1: 0.25rem; -$size-2: 0.5rem; -$size-4: 1rem; -$size-5: 1.5rem; -$size-6: 2rem; - -.dashboard-header { - display: flex; - align-items: center; - justify-content: space-between; - background-color: $color-white; - height: 63px; - padding: $size-1 $size-4 $size-1 $size-2; - position: relative; - z-index: 10; - user-select: none; - &.team { - display: grid; - grid-template-columns: 20% 1fr 20%; - } - - .element-name { - margin-right: $size-2; - } - - .btn-secondary { - flex-shrink: 0; - z-index: 10; - height: 32px; - svg { - height: 16px; - width: 16px; - } - } - - svg { - fill: $color-black; - height: 14px; - margin-right: $size-1; - width: 14px; - } - - nav { - display: flex; - align-items: flex-end; - justify-content: center; - z-index: 1; - - ul { - display: flex; - font-size: $fs14; - justify-content: center; - margin: 0; - } - - li { - a { - display: flex; - align-items: center; - flex-basis: 140px; - border-bottom: 3px solid transparent; - color: $color-gray-30; - height: 40px; - padding: $size-1 $size-5; - font-weight: $fw400; - &:hover { - color: $color-black; - text-decoration: none; - } - } - - &.active { - a { - color: $color-black; - border-color: $color-primary; - } - } - } - } - - .dashboard-title { - display: flex; - align-items: center; - margin-left: 13px; - - h1 { - color: $color-black; - display: flex; - flex-shrink: 0; - font-size: $fs22; - font-weight: $fw600; - z-index: 10; - user-select: all; - } - - .context-menu.is-open { - margin-top: 10px; - } - } - - .icon { - display: flex; - align-items: center; - cursor: pointer; - margin-left: $size-2; - z-index: 10; - - svg { - fill: $color-gray-40; - width: 15px; - height: 15px; - - &:hover { - fill: $color-primary-dark; - } - } - } - - .dashboard-buttons { - display: flex; - justify-content: flex-end; - align-items: center; - } - - .dashboard-header-actions { - display: flex; - } - - .pin-icon { - margin: 0 $size-2 0 $size-5; - background-color: transparent; - border: none; - svg { - fill: $color-gray-20; - } - - &.active { - svg { - fill: $color-gray-50; - } - } - } -} - -.dashboard-header { - background-color: transparent; - .dashboard-title { - h1 { - color: $df-primary; - font-size: 24px; - font-weight: 400; - width: 100%; - text-overflow: ellipsis; - overflow: hidden; - white-space: nowrap; - display: block; - max-width: 700px; - } - } - .icon { - svg { - fill: $df-secondary; - } - } - - // Settings sub-menu - .dashboard-header-options { - li { - a { - font-size: 16px; - color: $df-secondary; - border-color: transparent; - &:hover { - color: $df-primary; - } - } - &.active { - a { - color: $df-primary; - } - } - } - } -} +@use "common/refactor/common-refactor.scss" as *; +@use "common/refactor/common-dashboard"; .dashboard-container { - background-color: $color-dashboard; flex: 1 0 0; - margin-right: $size-4; + margin-right: $s-16; overflow-y: auto; width: 100%; + border-top: $s-1 solid $db-cuaternary; + &.dashboard-projects { user-select: none; } - &.no-bg { - background-color: transparent; - } &.dashboard-shared { - width: calc(100vw - 320px); - margin-right: 50px; + width: calc(100vw - $s-320); + margin-right: $s-52; } &.search { - margin-top: 10px; - } -} - -.dashboard-container { - background-color: transparent; - border-top: 1px solid $db-cuaternary; - - .dashboard-settings { - a { - color: $df-secondary; - } - .form-container { - width: 800px; - margin: 80px auto auto 120px; - form { - width: 468px; - .fields-row { - .custom-input, - .custom-select { - flex-direction: column-reverse; - label { - position: relative; - text-transform: uppercase; - color: $df-primary; - font-size: 11px; - margin-bottom: 12px; - margin-left: -4px; - } - input, - select { - background-color: $db-tertiary; - border-radius: 8px; - border-color: transparent; - color: $df-primary; - padding: 0 15px; - &:focus { - outline: 1px solid $da-primary; - } - ::placeholder { - color: $df-secondary; - } - } - .help-icon { - bottom: 12px; - top: auto; - svg { - fill: $df-secondary; - } - } - &.disabled { - input { - background-color: $db-primary; - border-color: $db-cuaternary; - color: $df-secondary; - } - } - .input-container { - background-color: $db-tertiary; - border-radius: 8px; - border-color: transparent; - margin-top: 22px; - .main-content { - label { - position: absolute; - top: -24px; - } - span { - color: $df-primary; - } - } - &:focus { - border: 1px solid $da-primary; - } - } - textarea { - border-radius: 8px; - padding: 12px 14px; - background-color: $db-tertiary; - color: $df-primary; - border: none; - &:focus { - outline: 1px solid $da-primary; - } - } - } - } - .field-title { - color: $df-primary; - } - .field-title:not(:first-child) { - margin-top: 64px; - } - - .field-text { - color: $df-secondary; - } - button, - .btn-secondary { - width: 100%; - font-size: 11px; - text-transform: uppercase; - background-color: $db-tertiary; - color: $df-primary; - &:hover { - color: $da-primary; - background-color: $db-cuaternary; - } - } - hr { - display: none; - } - } - .links { - margin-top: 12px; - } - } - } - - //Access tokens - .dashboard-access-tokens { - width: 800px; - margin-left: 120px; - margin-top: 80px; - .access-tokens-hero-container { - background-color: transparent; - .access-tokens-hero { - width: 468px; - flex-direction: column; - gap: 32px; - background-color: transparent; - margin: 0; - padding: 0; - .desc { - background-color: transparent; - width: 100%; - h2 { - color: $df-primary; - font-size: 24px; - font-weight: regular; - margin-bottom: 32px; - } - p { - color: $df-secondary; - margin-bottom: 0; - font-size: 14px; - } - } - button { - width: 100%; - font-size: 11px; - text-transform: uppercase; - background-color: $db-tertiary; - color: $df-primary; - &:hover { - color: $da-primary; - background-color: $db-cuaternary; - } - } - } - } - .dashboard-table { - width: 800px; - .table-rows { - padding-top: 0; - .table-row { - font-size: 14px; - min-height: 40px; - height: fit-content; - .name { - color: $df-primary; - max-width: 480px; - overflow: hidden; - text-overflow: ellipsis; - display: -webkit-box; - -webkit-line-clamp: 2; - -webkit-box-orient: vertical; - } - .expiration-date { - color: $df-secondary; - } - } - } - } - .access-tokens-empty { - width: 468px; - border: 1px solid $db-cuaternary; - border-radius: 8px; - margin-top: 32px; - font-size: 14px; - background-color: transparent; - color: $df-secondary; - } - } - - // Team webhooks - &.dashboard-team-webhooks { - width: 800px; - margin-left: 120px; - margin-top: 80px; - border: none; - align-items: flex-start; - .webhooks-hero-container { - width: 468px; - background-color: transparent; - .webhooks-hero { - width: 468px; - flex-direction: column; - gap: 32px; - background-color: transparent; - margin: 0; - padding: 0; - .desc { - background-color: transparent; - width: 100%; - h2 { - color: $df-primary; - font-size: 24px; - font-weight: regular; - margin-bottom: 32px; - } - p { - color: $df-secondary; - margin-bottom: 0; - font-size: 14px; - } - } - .btn-primary { - width: 100%; - font-size: 11px; - text-transform: uppercase; - background-color: $db-tertiary; - color: $df-primary; - &:hover { - color: $da-primary; - background-color: $db-cuaternary; - } - } - } - } - .dashboard-table { - width: 800px; - .table-rows { - padding-top: 0; - .table-row { - font-size: 14px; - min-height: 40px; - height: fit-content; - .name { - color: $df-primary; - max-width: 480px; - } - .expiration-date { - color: $df-secondary; - } - } - } - } - .webhooks-empty { - width: 468px; - border: 1px solid $db-cuaternary; - border-radius: 8px; - margin-top: 32px; - font-size: 14px; - background-color: transparent; - color: $df-secondary; - } - } - - // Members section - .dashboard-table { - .table-header { - background-color: transparent; - color: $df-secondary; - font-size: 12px; - text-transform: uppercase; - } - .table-rows { - .table-row { - background-color: $db-tertiary; - border-radius: 8px; - color: $df-primary; - .rol-selector { - background-color: $db-cuaternary; - border-color: transparent; - border-radius: 8px; - } - } - } - .member-info { - .member-name .you, - .member-email { - color: $df-secondary; - } - } - .status-badge { - border-radius: 8px; - color: $db-primary; - text-transform: uppercase; - } - .empty-invitations { - border: 1px solid $db-cuaternary; - border-radius: 8px; - color: $df-secondary; - } - } - .actions-dropdown, - .options-dropdown { - background-color: $db-tertiary; - border: 1px solid $db-cuaternary; - border-radius: 8px; - min-width: 252px; - - .separator { - border-color: transparent; - margin-top: 10px; - } - - li { - border-radius: 8px; - height: 40px; - margin: 5px; - color: $df-primary; - - &:hover { - background-color: $db-cuaternary; - } - } - - &.options-dropdown { - li { - color: $df-primary; - &.warning { - color: $color-danger; - } - } - } + margin-top: $s-12; } } .dashboard-project-row { - margin-bottom: $size-5; + margin-bottom: $s-24; position: relative; .project { align-items: center; - background: $color-white; - border-radius: $br3; + background: $df-primary; + border-radius: $br-4; display: flex; flex-direction: row; justify-content: space-between; align-items: center; - margin-top: $size-4; - padding: $size-2 $size-2 $size-2 $size-4; + margin-top: $s-16; + padding: $s-8 $s-8 $s-8 $s-16; width: 99%; - max-height: 40px; - gap: $size-2; + max-height: $s-40; + gap: $s-8; + .project-name-wrapper { display: flex; align-items: center; justify-content: flex-start; - min-height: 32px; - margin-left: $size-2; + min-height: $s-32; + margin-left: $s-8; } .show-more { align-items: center; - color: $color-gray-30; + color: $df-secondary; display: flex; - font-size: $fs14; + font-size: $fs-14; justify-content: space-between; cursor: pointer; background-color: transparent; border: none; .placeholder-icon { transform: rotate(-90deg); - margin-left: 10px; + margin-left: $s-12; svg { - height: 14px; - width: 14px; - fill: $color-gray-30; + height: $s-16; + width: $s-16; + fill: $df-secondary; } } &:hover { - color: $color-primary-dark; + color: $da-tertiary; svg { - fill: $color-primary-dark; + fill: $da-tertiary; } } } .btn-secondary { border: none; - padding: $size-2; + padding: $s-8; } h2 { cursor: pointer; - font-size: $fs18; - line-height: $lh-088; // Original value was 1rem = 16px; 16px/18px = 88.88888% => $lh-088 - font-weight: $fw600; - color: $color-black; - margin-right: $size-1; + font-size: $fs-16; + line-height: 0.8; + font-weight: $fw700; + color: $db-secondary; + margin-right: $s-4; + margin-right: $s-12; } - .edit-wrapper { - margin-right: $size-4; - } - - .info { - font-size: $fs14; - line-height: $lh-115; // Original value was 1rem = 16px; 16px/14px = 114.285714286% => $lh-115 (rounded) + .info, + .recent-files-row-title-info { + font-size: $fs-14; + line-height: 1.15; font-weight: $fw400; - color: $color-gray-60; - margin-left: 0.75rem; + color: $db-primary; @media (max-width: 760px) { display: none; } @@ -637,15 +107,19 @@ $size-6: 2rem; .project-actions { display: flex; opacity: 1; - margin-left: $size-6; + margin-left: $s-32; .btn-small { - height: 32px; - margin: 0 $size-2; - width: 32px; + height: $s-32; + margin: 0 $s-8; + width: $s-32; + + &:not(:hover) { + background: transparent; + } svg { - height: 16px; - width: 16px; + height: $s-16; + width: $s-16; } } } @@ -654,18 +128,18 @@ $size-6: 2rem; cursor: pointer; display: flex; align-items: center; - margin-right: 14px; + margin-right: $s-16; background-color: transparent; border: none; svg { - width: 15px; - height: 15px; - fill: $color-gray-20; + width: $s-16; + height: $s-16; + fill: $df-secondary; } &.active { svg { - fill: $color-gray-50; + fill: $db-tertiary; } } } @@ -681,29 +155,29 @@ $size-6: 2rem; .show-more { align-items: center; - color: $color-gray-30; + color: $df-secondary; display: flex; - font-size: $fs14; + font-size: $fs-14; justify-content: space-between; cursor: pointer; background-color: transparent; border: none; position: absolute; - top: 9px; - right: 53px; + top: $s-8; + right: $s-52; .placeholder-icon { transform: rotate(-90deg); - margin-left: 10px; + margin-left: $s-8; svg { - height: 14px; - width: 14px; - fill: $color-gray-30; + height: $s-16; + width: $s-16; + fill: $df-secondary; } } &:hover { - color: $color-primary-dark; + color: $da-tertiary; svg { - fill: $color-primary-dark; + fill: $da-tertiary; } } } @@ -717,7 +191,8 @@ $size-6: 2rem; font-weight: 400; } span, - .info { + .info, + .recent-files-row-title-info { color: $df-secondary; } .project-actions { @@ -731,135 +206,165 @@ $size-6: 2rem; } .team-hero { + background-color: $db-tertiary; + border-radius: $br-8; + border: none; display: flex; + margin: $s-16; + padding: $s-8; position: relative; - border: 2px solid $color-gray-10; - border-radius: $br8; - padding: 20px; - margin: 0 1rem 0 21px; - height: 154px; .text { + display: flex; + flex-direction: column; + align-items: flex-start; + flex-grow: 1; - padding-left: 20px; - .title { - font-size: $fs24; - font-weight: $fw700; - color: $color-black; + padding: $s-20 $s-20; + } + .title { + font-size: $fs-24; + color: $df-primary; + font-weight: $fw400; + } + .info { + flex: 1; + font-size: $fs-16; + span { + color: $df-secondary; + display: block; } - .info { - span { - color: $color-gray-30; - display: block; - } - padding-top: 10px; + a { + color: $da-primary; } + padding-top: $s-8; } .close { position: absolute; - top: 20px; - right: 20px; + top: $s-20; + right: $s-20; background-color: transparent; border: none; cursor: pointer; svg { transform: rotate(45deg); - width: 16px; - height: 16px; + width: $s-16; + height: $s-16; } } .invite { - align-self: flex-end; - height: 40px; - font-family: "worksans", sans-serif; - width: 180px; + height: $s-32; + width: $s-180; } + .img-wrapper { + display: flex; + align-items: center; + justify-content: center; + width: $s-200; + height: $s-200; + overflow: hidden; + border-radius: $br-4; + } + img { - width: 274px; - margin-bottom: -19px; + border-radius: $br-4; + height: $s-200; + width: auto; + @media (max-width: 1200px) { display: none; width: 0; } } + svg { + fill: $df-secondary; + } } .hero-projects { display: grid; grid-template-columns: 1fr 1fr; - grid-gap: 30px; - margin: 0 1rem 1rem 1.2rem; + grid-gap: $s-32; + margin: 0 $s-16 $s-16 $s-20; + + @media (max-width: 1366px) { + grid-template-columns: 1fr; + } + .tutorial, .walkthrough { display: grid; - grid-template-columns: 1fr 1fr; + grid-template-columns: auto 1fr; position: relative; - border: 2px solid $color-gray-10; - border-radius: $br8; - min-height: 211px; + border-radius: $br-8; + min-height: $s-216; + background-color: $db-tertiary; + padding: $s-8; .thumbnail { - border-top-left-radius: $br6; - border-bottom-left-radius: $br6; - padding: 30px; + width: $s-200; + height: $s-200; + border-radius: $br-6; + padding: $s-32; display: block; - background-color: #e0e4e9; + background-color: var(--color-canvas); + } + + img { + border-radius: $br-4; + margin-bottom: 0; + width: $s-232; } .text { - padding: 30px; - .title { - color: $color-black; - font-size: $fs24; - font-weight: $fw700; - margin-bottom: 8px; - } - .info { - color: $color-gray-50; - margin-bottom: 20px; - font-size: $fs14; - } + padding: $s-32; + display: flex; + flex-direction: column; + } + + .title { + color: $df-primary; + font-size: $fs-24; + font-weight: $fw400; + margin-bottom: $s-8; + } + .info { + flex: 1; + color: $df-secondary; + margin-bottom: $s-20; + font-size: $fs-16; + } + .invite { + height: $s-32; } .action { - font-family: "worksans", sans-serif; - width: 180px; - height: 40px; + width: $s-180; + height: $s-40; } .close { position: absolute; top: 0; right: 0; - width: $size-5; + width: $s-24; cursor: pointer; display: flex; - margin: 20px; + margin: $s-20; justify-content: center; align-items: center; background-color: transparent; border: none; .icon { svg { - fill: $color-gray-30; - height: 16px; - width: 16px; + fill: $df-secondary; + height: $s-16; + width: $s-16; transform: rotate(45deg); &:hover { - fill: $color-primary; + fill: $da-tertiary; } } } } - - @media (max-width: 1846px) { - grid-template-columns: 190px 1fr; - } - @media (max-width: 1526px) { - grid-template-columns: 1fr; - .img { - display: none; - width: 0; - } - } } .walkthrough { .thumbnail { @@ -879,31 +384,8 @@ $size-6: 2rem; .loader { display: flex; svg#loader-pencil { - width: 31px; + width: $s-32; } } } } - -.btn-secondary { - background-color: $db-tertiary; - text-transform: uppercase; - border: none; - color: $df-primary; - border-radius: 8px; - - font-size: 0.75rem; - padding: 0 1rem; - cursor: pointer; - display: flex; - justify-content: center; - align-items: center; - - &:hover { - background-color: $db-cuaternary; - color: $da-primary; - svg { - fill: $da-primary; - } - } -} diff --git a/frontend/src/app/main/ui/dashboard/search.cljs b/frontend/src/app/main/ui/dashboard/search.cljs index ad9f517bf3..1f47edb4ed 100644 --- a/frontend/src/app/main/ui/dashboard/search.cljs +++ b/frontend/src/app/main/ui/dashboard/search.cljs @@ -96,7 +96,3 @@ :hide-new? true :origin :search :limit limit}])]]))) - - - - diff --git a/frontend/src/app/main/ui/dashboard/search.scss b/frontend/src/app/main/ui/dashboard/search.scss index 016cd99969..9eb379706f 100644 --- a/frontend/src/app/main/ui/dashboard/search.scss +++ b/frontend/src/app/main/ui/dashboard/search.scss @@ -1,325 +1,49 @@ -@import "common/dependencies/colors"; +// 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 -$br0: 0; -$br3: 3px; -$br8: 8px; -$br6: 6px; -$br12: 12px; -$fs14: 0.875rem; -$fs16: 1rem; -$fs18: 1.125rem; -$fs22: 1.375rem; -$fs24: 1.5rem; -$fw400: 400; -$fw600: 600; -$fw700: 700; -$lh-088: 0.88; -$lh-115: 1.15; // original $title-lh-sm -$size-1: 0.25rem; -$size-2: 0.5rem; -$size-4: 1rem; -$size-5: 1.5rem; -$size-6: 2rem; - -.dashboard-header { - display: flex; - align-items: center; - justify-content: space-between; - background-color: $color-white; - height: 63px; - padding: $size-1 $size-4 $size-1 $size-2; - position: relative; - z-index: 10; - user-select: none; - &.team { - display: grid; - grid-template-columns: 20% 1fr 20%; - } - - .element-name { - margin-right: $size-2; - } - - .btn-secondary { - flex-shrink: 0; - z-index: 10; - height: 32px; - } - - svg { - fill: $color-black; - height: 14px; - margin-right: $size-1; - width: 14px; - } - - nav { - display: flex; - align-items: flex-end; - justify-content: center; - z-index: 1; - - ul { - display: flex; - font-size: $fs14; - justify-content: center; - margin: 0; - } - - li { - a { - display: flex; - align-items: center; - flex-basis: 140px; - border-bottom: 3px solid transparent; - color: $color-gray-30; - height: 40px; - padding: $size-1 $size-5; - font-weight: $fw400; - &:hover { - color: $color-black; - text-decoration: none; - } - } - - &.active { - a { - color: $color-black; - border-color: $color-primary; - } - } - } - } - - .dashboard-title { - display: flex; - align-items: center; - margin-left: 13px; - - h1 { - color: $color-black; - display: flex; - flex-shrink: 0; - font-size: $fs22; - font-weight: $fw600; - z-index: 10; - user-select: all; - } - - .context-menu.is-open { - margin-top: 10px; - } - } - - .icon { - display: flex; - align-items: center; - cursor: pointer; - margin-left: $size-2; - z-index: 10; - - svg { - fill: $color-gray-40; - width: 15px; - height: 15px; - - &:hover { - fill: $color-primary-dark; - } - } - } - - .dashboard-buttons { - display: flex; - justify-content: flex-end; - align-items: center; - } - - .dashboard-header-actions { - display: flex; - } - - .pin-icon { - margin: 0 $size-2 0 $size-5; - background-color: transparent; - border: none; - svg { - fill: $color-gray-20; - } - - &.active { - svg { - fill: $color-gray-50; - } - } - } -} - -.grid-empty-placeholder { - border-radius: $br12; - display: grid; - background-color: rgba(227, 227, 227, 0.3); - padding: 13px; - margin-right: 13px; - height: 230px; - &.loader { - justify-items: center; - } - .icon { - display: flex; - align-items: center; - justify-content: center; - } - &.libs { - background-image: url(/images/ph-left.svg), url(/images/ph-right.svg); - background-position: - 15% bottom, - 85% top; - background-repeat: no-repeat; - align-items: center; - border: 1px dashed #b1b2b5; - border-radius: $br3; - display: flex; - flex-direction: column; - height: 200px; - margin: 1rem; - padding: 3rem; - justify-content: center; - .text { - p { - max-width: 360px; - text-align: center; - font-size: $fs16; - } - } - } - .create-new { - background-color: white; - border: 2px solid $color-gray-10; - border-radius: $br3; - color: $color-black; - cursor: pointer; - height: 158px; - font-family: "worksans", sans-serif; - margin: 0.5rem; - &:hover { - border: 2px solid $color-primary; - } - } - - &.search { - align-items: center; - display: flex; - justify-content: center; - flex-direction: column; - height: 200px; - // background: $color-white; - border: 1px dashed #e3e3e3; - border-radius: $br0; - } - - svg { - width: 36px; - height: 36px; - fill: $color-gray-20; - } - - .text { - margin-top: 10px; - color: $color-gray-30; - font-size: $fs16; - } -} +@use "common/refactor/common-refactor.scss" as *; +@use "common/refactor/common-dashboard"; +@use "./placeholder.scss"; .dashboard-container { - background-color: $color-dashboard; flex: 1 0 0; - margin-right: $size-4; + margin-right: $s-16; overflow-y: auto; width: 100%; + border-top: $s-1 solid $db-cuaternary; + &.dashboard-projects { user-select: none; } - &.no-bg { - background-color: transparent; - } &.dashboard-shared { - width: calc(100vw - 320px); - margin-right: 50px; + width: calc(100vw - $s-320); + margin-right: $s-52; } &.search { - margin-top: 10px; + margin-top: $s-12; } } -.dashboard-header { - background-color: transparent; - .dashboard-title { - h1 { - color: $df-primary; - font-size: 24px; - font-weight: 400; - width: 100%; - text-overflow: ellipsis; - overflow: hidden; - white-space: nowrap; - display: block; - max-width: 700px; - } - } - .icon { - svg { - fill: $df-secondary; - } - } +.grid-empty-placeholder.search { + align-items: center; + display: flex; + justify-content: center; + flex-direction: column; + height: $s-200; + background: transparent; + border: $s-1 solid $db-cuaternary; + border-radius: $br-8; - // Settings sub-menu - .dashboard-header-options { - li { - a { - font-size: 16px; - color: $df-secondary; - border-color: transparent; - &:hover { - color: $df-primary; - } - } - &.active { - a { - color: $df-primary; - } - } - } - } -} - -.grid-empty-placeholder { - background-color: transparent; - - .create-new { - background-color: $db-tertiary; - border-radius: 8px; - border: none; + .text { color: $df-primary; - text-transform: uppercase; - - &:hover { - background-color: $db-cuaternary; - color: $da-primary; - } } - - &.search { - border: 1px solid $db-cuaternary; - border-radius: 8px; - .text { - color: $df-primary; - } - .icon { - svg { - fill: $df-secondary; - } - } + .icon svg { + fill: $df-secondary; + width: $s-32; + height: $s-32; } } diff --git a/frontend/src/app/main/ui/dashboard/sidebar.cljs b/frontend/src/app/main/ui/dashboard/sidebar.cljs index 71840fed43..1994630986 100644 --- a/frontend/src/app/main/ui/dashboard/sidebar.cljs +++ b/frontend/src/app/main/ui/dashboard/sidebar.cljs @@ -21,7 +21,7 @@ [app.main.ui.components.dropdown-menu :refer [dropdown-menu dropdown-menu-item*]] [app.main.ui.components.link :refer [link]] [app.main.ui.context :as ctx] - [app.main.ui.dashboard.comments :refer [comments-section]] + [app.main.ui.dashboard.comments :refer [comments-icon comments-section]] [app.main.ui.dashboard.inline-edition :refer [inline-edition]] [app.main.ui.dashboard.project-menu :refer [project-menu]] [app.main.ui.dashboard.team-form] @@ -909,112 +909,135 @@ (st/emit! (ptk/event ::ev/event {::ev/name "show-release-notes" :version version})) (if (and (kbd/alt? event) (kbd/mod? event)) (st/emit! (modal/show {:type :onboarding})) - (st/emit! (modal/show {:type :release-notes :version version}))))))] + (st/emit! (modal/show {:type :release-notes :version version})))))) + show-comments* (mf/use-state false) + show-comments? @show-comments* + + handle-hide-comments + (mf/use-callback + (fn [] + (reset! show-comments* false))) + + handle-show-comments + (mf/use-callback + (fn [] + (reset! show-comments* true)))] (if new-css-system - [:div {:class (stl/css :profile-section)} - [:div {:class (stl/css :profile) - :tab-index "0" - :on-click (fn [event] - (dom/stop-propagation event) - (reset! show true)) - :on-key-down (fn [event] - (when (kbd/enter? event) - (reset! show true))) - :data-test "profile-btn"} - [:img {:src photo - :alt (:fullname profile)}] - [:span (:fullname profile)]] - - [:& dropdown-menu {:on-close (fn [event] - (dom/stop-propagation event) - (reset! show false)) - :show @show} - [:ul {:class (stl/css :dropdown)} - [:li {:tab-index (if show "0" "-1") - :on-click (partial on-click :settings-profile) - :on-key-down (fn [event] - (when (kbd/enter? event) - (on-click :settings-profile event))) - :data-test "profile-profile-opt"} - [:span {:class (stl/css :text)} (tr "labels.your-account")]] - - [:li {:class (stl/css :separator) - :tab-index (if show "0" "-1") - :on-click #(dom/open-new-window "https://help.penpot.app") - :on-key-down (fn [event] - (when (kbd/enter? event) - (dom/open-new-window "https://help.penpot.app"))) - :data-test "help-center-profile-opt"} - [:span {:class (stl/css :text)} (tr "labels.help-center")]] - - [:li {:tab-index (if show "0" "-1") - :on-click #(dom/open-new-window "https://community.penpot.app") - :on-key-down (fn [event] - (when (kbd/enter? event) - (dom/open-new-window "https://community.penpot.app")))} - [:span {:class (stl/css :text)} (tr "labels.community")]] - - [:li {:tab-index (if show "0" "-1") - :on-click #(dom/open-new-window "https://www.youtube.com/c/Penpot") - :on-key-down (fn [event] - (when (kbd/enter? event) - (dom/open-new-window "https://www.youtube.com/c/Penpot")))} - [:span {:class (stl/css :text)} (tr "labels.tutorials")]] - - [:li {:tab-index (if show "0" "-1") - :on-click show-release-notes - :on-key-down (fn [event] - (when (kbd/enter? event) - (show-release-notes)))} - [:span {:class (stl/css :text)} (tr "labels.release-notes")]] - - [:li {:class (stl/css :separator) - :tab-index (if show "0" "-1") - :on-click #(dom/open-new-window "https://penpot.app/libraries-templates") - :on-key-down (fn [event] - (when (kbd/enter? event) - (dom/open-new-window "https://penpot.app/libraries-templates"))) - :data-test "libraries-templates-profile-opt"} - [:span {:class (stl/css :text)} (tr "labels.libraries-and-templates")]] - - [:li {:tab-index (if show "0" "-1") - :on-click #(dom/open-new-window "https://github.com/penpot/penpot") - :on-key-down (fn [event] - (when (kbd/enter? event) - (dom/open-new-window "https://github.com/penpot/penpot")))} - [:span {:class (stl/css :text)} (tr "labels.github-repo")]] - - [:li {:tab-index (if show "0" "-1") - :on-click #(dom/open-new-window "https://penpot.app/terms") - :on-key-down (fn [event] - (when (kbd/enter? event) - (dom/open-new-window "https://penpot.app/terms")))} - [:span {:class (stl/css :text)} (tr "auth.terms-of-service")]] - - (when (contains? cf/flags :user-feedback) - [:li {:class (stl/css :separator) - :tab-index (if show "0" "-1") - :on-click (partial on-click :settings-feedback) - :on-key-down (fn [event] - (when (kbd/enter? event) - (on-click :settings-feedback event))) - :data-test "feedback-profile-opt"} - [:span {:class (stl/css :text)} (tr "labels.give-feedback")]]) - - [:li {:class (stl/css :separator) - :tab-index (if show "0" "-1") - :on-click #(on-click (du/logout) %) - :on-key-down (fn [event] - (when (kbd/enter? event) - (on-click (du/logout) event))) - :data-test "logout-profile-opt"} - [:span {:class (stl/css :icon)} i/exit] - [:span {:class (stl/css :text)} (tr "labels.logout")]]]] - + [:* (when (and team profile) - [:& comments-section {:profile profile - :team team}])] + [:& comments-section + {:profile profile + :team team + :show? show-comments? + :on-show-comments handle-show-comments + :on-hide-comments handle-hide-comments}]) + + [:div {:class (stl/css :profile-section)} + [:div {:class (stl/css :profile) + :tab-index "0" + :on-click (fn [event] + (dom/stop-propagation event) + (reset! show true)) + :on-key-down (fn [event] + (when (kbd/enter? event) + (reset! show true))) + :data-test "profile-btn"} + [:img {:src photo + :alt (:fullname profile)}] + [:span (:fullname profile)]] + + [:& dropdown-menu {:on-close (fn [event] + (dom/stop-propagation event) + (reset! show false)) + :show @show} + [:ul {:class (stl/css :dropdown)} + [:li {:tab-index (if show "0" "-1") + :on-click (partial on-click :settings-profile) + :on-key-down (fn [event] + (when (kbd/enter? event) + (on-click :settings-profile event))) + :data-test "profile-profile-opt"} + [:span {:class (stl/css :text)} (tr "labels.your-account")]] + + [:li {:class (stl/css :separator) + :tab-index (if show "0" "-1") + :on-click #(dom/open-new-window "https://help.penpot.app") + :on-key-down (fn [event] + (when (kbd/enter? event) + (dom/open-new-window "https://help.penpot.app"))) + :data-test "help-center-profile-opt"} + [:span {:class (stl/css :text)} (tr "labels.help-center")]] + + [:li {:tab-index (if show "0" "-1") + :on-click #(dom/open-new-window "https://community.penpot.app") + :on-key-down (fn [event] + (when (kbd/enter? event) + (dom/open-new-window "https://community.penpot.app")))} + [:span {:class (stl/css :text)} (tr "labels.community")]] + + [:li {:tab-index (if show "0" "-1") + :on-click #(dom/open-new-window "https://www.youtube.com/c/Penpot") + :on-key-down (fn [event] + (when (kbd/enter? event) + (dom/open-new-window "https://www.youtube.com/c/Penpot")))} + [:span {:class (stl/css :text)} (tr "labels.tutorials")]] + + [:li {:tab-index (if show "0" "-1") + :on-click show-release-notes + :on-key-down (fn [event] + (when (kbd/enter? event) + (show-release-notes)))} + [:span {:class (stl/css :text)} (tr "labels.release-notes")]] + + [:li {:class (stl/css :separator) + :tab-index (if show "0" "-1") + :on-click #(dom/open-new-window "https://penpot.app/libraries-templates") + :on-key-down (fn [event] + (when (kbd/enter? event) + (dom/open-new-window "https://penpot.app/libraries-templates"))) + :data-test "libraries-templates-profile-opt"} + [:span {:class (stl/css :text)} (tr "labels.libraries-and-templates")]] + + [:li {:tab-index (if show "0" "-1") + :on-click #(dom/open-new-window "https://github.com/penpot/penpot") + :on-key-down (fn [event] + (when (kbd/enter? event) + (dom/open-new-window "https://github.com/penpot/penpot")))} + [:span {:class (stl/css :text)} (tr "labels.github-repo")]] + + [:li {:tab-index (if show "0" "-1") + :on-click #(dom/open-new-window "https://penpot.app/terms") + :on-key-down (fn [event] + (when (kbd/enter? event) + (dom/open-new-window "https://penpot.app/terms")))} + [:span {:class (stl/css :text)} (tr "auth.terms-of-service")]] + + (when (contains? cf/flags :user-feedback) + [:li {:class (stl/css :separator) + :tab-index (if show "0" "-1") + :on-click (partial on-click :settings-feedback) + :on-key-down (fn [event] + (when (kbd/enter? event) + (on-click :settings-feedback event))) + :data-test "feedback-profile-opt"} + [:span {:class (stl/css :text)} (tr "labels.give-feedback")]]) + + [:li {:class (stl/css :separator) + :tab-index (if show "0" "-1") + :on-click #(on-click (du/logout) %) + :on-key-down (fn [event] + (when (kbd/enter? event) + (on-click (du/logout) event))) + :data-test "logout-profile-opt"} + [:span {:class (stl/css :icon)} i/exit] + [:span {:class (stl/css :text)} (tr "labels.logout")]]]] + + (when (and team profile) + [:& comments-icon + {:profile profile + :show? show-comments? + :on-show-comments handle-show-comments}])]] ;; OLD [:div.profile-section @@ -1127,8 +1150,12 @@ [:span.text (tr "labels.logout")]]]] (when (and team profile) - [:& comments-section {:profile profile - :team team}])]))) + [:& comments-section + {:profile profile + :team team + :show? show-comments? + :on-show-comments handle-show-comments + :on-hide-comments handle-hide-comments}])]))) (mf/defc sidebar {::mf/wrap-props false diff --git a/frontend/src/app/main/ui/dashboard/sidebar.scss b/frontend/src/app/main/ui/dashboard/sidebar.scss index 687d3a9689..0d745a0799 100644 --- a/frontend/src/app/main/ui/dashboard/sidebar.scss +++ b/frontend/src/app/main/ui/dashboard/sidebar.scss @@ -1,20 +1,20 @@ -@import "common/dependencies/colors"; -$fs14: 0.875rem; -$fs12: 0.75rem; -$fw400: 400; -$size-2: 0.5rem; -$size-3: 0.75rem; -$size-4: 1rem; -$br3: 3px; +// 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 *; +@use "common/refactor/common-dashboard"; .dashboard-sidebar { grid-row: 1 / span 2; grid-column: 1 / span 2; background-color: $db-primary; - border-right: 1px solid $db-cuaternary; - margin: 0 1rem 0 0; - padding: 1rem 0 0 0; + border-right: $s-1 solid $db-cuaternary; + margin: 0 $s-16 0 0; + padding: $s-16 0 0 0; z-index: 1; display: flex; @@ -31,31 +31,22 @@ $br3: 3px; hr { border-color: transparent; - margin: 0.8rem 15px; - } - - .back-to-dashboard { - .icon svg { - fill: $df-secondary; - } - .text { - color: $df-primary; - } + margin: $s-12 $s-16; } } .sidebar-team-switch { position: relative; display: flex; - margin: 5px 15px; + margin: $s-4 $s-16; .switch-content { background-color: $db-tertiary; - border-radius: 8px; - height: 48px; + border-radius: $br-8; + height: $s-48; display: flex; width: 100%; - border: 1px solid transparent; + border: $s-1 solid transparent; align-items: center; svg { @@ -70,8 +61,8 @@ $br3: 3px; svg { fill: $df-secondary; - width: 10px; - height: 10px; + width: $s-12; + height: $s-12; } } @@ -81,23 +72,23 @@ $br3: 3px; display: flex; align-items: center; flex-grow: 1; - font-size: 0.875rem; - padding: 0px 10px; + font-size: $fs-14; + padding: 0 $s-12; background-color: transparent; border: none; - border-right: 1px solid $db-primary; + border-right: $s-1 solid $db-primary; } .team-name { flex-grow: 1; display: flex; - height: 40px; + height: $s-40; align-items: center; } .team-text { color: $df-primary; - width: 145px; + width: $s-144; text-overflow: ellipsis; white-space: nowrap; overflow: hidden; @@ -107,26 +98,26 @@ $br3: 3px; .team-icon { display: flex; align-items: center; - padding-right: 10px; + padding-right: $s-12; img { border-radius: 50%; flex-shrink: 0; - height: 23px; - width: 23px; + height: $s-24; + width: $s-24; } svg { - width: 23px; - height: 23px; + width: $s-24; + height: $s-24; } } .switch-options { display: flex; - max-width: 22px; - min-width: 28px; - border-left: 1px solid #e3e3e3; + max-width: $s-24; + min-width: $s-28; + border-left: $s-1 solid $df-primary; justify-content: center; align-items: center; cursor: pointer; @@ -135,16 +126,16 @@ $br3: 3px; svg { fill: $df-secondary; - width: 15px; - height: 13px; + width: $s-16; + height: $s-12; } } .dropdown { - right: 2px; - top: 50px; - min-width: 162px; - max-height: 30rem; + right: $s-2; + top: $s-52; + min-width: $s-160; + max-height: $s-480; } } @@ -152,36 +143,36 @@ $br3: 3px; position: absolute; z-index: 12; background-color: $db-tertiary; - border: 1px solid $db-cuaternary; - border-radius: 8px; + border: $s-1 solid $db-cuaternary; + border-radius: $br-8; box-shadow: 0px 2px 8px rgba(0, 0, 0, 0.25); .separator { border-color: transparent; - margin-top: 10px; + margin-top: $s-12; } li { - border-radius: 8px; - height: 40px; - margin: 5px; + border-radius: $br-8; + height: $s-40; + margin: $s-6; display: flex; align-items: center; cursor: pointer; - font-size: 0.875rem; - padding: 5px 16px; + font-size: $fs-14; + padding: $s-6 $s-16; .warning { - color: #e65244; + color: var(--dark-warning-color); } &:hover { background-color: $db-cuaternary; } svg { - height: 12px; - width: 12px; + height: $s-12; + width: $s-12; } } @@ -194,7 +185,7 @@ $br3: 3px; li { color: $df-primary; &.warning { - color: $color-danger; + color: var(--dark-warning-color); } } } @@ -202,22 +193,22 @@ $br3: 3px; .teams-dropdown { background-color: $db-tertiary; - border-radius: 8px; - border: 1px solid $db-cuaternary; - min-width: 248px; + border-radius: $br-8; + border: $s-1 solid $db-cuaternary; + min-width: $s-248; left: 0; - top: 50px; + top: $s-52; z-index: 12; - max-height: 30rem; + max-height: $s-480; overflow-x: hidden; overflow-y: auto; li { - border-radius: 8px; - height: 42px; - padding: 0 5px; - margin: 5px; + border-radius: $br-8; + height: $s-40; + padding: 0 $s-6; + margin: $s-6; svg { fill: $df-secondary; @@ -240,7 +231,7 @@ $br3: 3px; } .team-text { color: $df-primary; - width: 165px; + width: $s-168; } .new-team { @@ -251,14 +242,14 @@ $br3: 3px; .team-icon { background-color: #2e3434; border-radius: 50%; - height: 24px; - margin-right: 10px; - padding: 6px; - width: 24px; + height: $s-24; + margin-right: $s-12; + padding: $s-6; + width: $s-24; svg { - height: 12px; - width: 12px; + height: $s-12; + width: $s-12; } } } @@ -266,52 +257,52 @@ $br3: 3px; } .sidebar-empty-placeholder { - padding: 10px 12px; + padding: $s-12; color: $df-secondary; display: flex; align-items: flex-start; .icon { - padding: 0px 10px; + padding: 0 $s-12; svg { - fill: $color-gray-30; - width: 12px; - height: 12px; + fill: $df-secondary; + width: $s-12; + height: $s-12; } } .text { - font-size: $fs12; + font-size: $fs-12; } } .sidebar-search { align-items: center; - border: 1px solid transparent; + border: $s-1 solid transparent; display: flex; - margin: 5px 15px; + margin: $s-6 $s-16; background-color: $db-tertiary; - border-radius: 8px; - margin-bottom: 2rem; + border-radius: $br-8; + margin-bottom: $s-32; margin-top: 0; position: relative; .input-text { background: transparent; border: 0; - font-size: 0.875rem; + font-size: $fs-14; margin: 0; width: 100%; - height: 40px; + height: $s-40; - border-radius: 8px; + border-radius: $br-8; color: $df-primary; max-width: 100%; - padding: 6px 10px; + padding: $s-6 $s-12; &:focus, &:focus-within { - border: 1px solid $da-primary; + border: $s-1 solid $da-primary; } } ::placeholder { @@ -323,19 +314,19 @@ $br3: 3px; align-items: center; cursor: pointer; display: flex; - height: 22px; + height: $s-24; margin-left: auto; - padding: 0 0.5rem; - width: 32px; + padding: 0 $s-8; + width: $s-32; position: absolute; - top: 10px; - right: 2px; + top: $s-12; + right: $s-2; svg { - fill: $color-gray-30; - height: 15px; - width: 15px; + fill: $df-secondary; + height: $s-16; + width: $s-16; } } @@ -343,7 +334,7 @@ $br3: 3px; transform: rotate(45deg); &:hover { - fill: $color-danger; + fill: var(--warning-color); } } } @@ -364,7 +355,7 @@ $br3: 3px; cursor: pointer; display: flex; flex-shrink: 0; - padding: 0.6rem 0.6rem 0.6rem 1.4rem; + padding: $s-8 $s-8 $s-8 $s-24; a { font-weight: $fw400; width: 100%; @@ -374,15 +365,15 @@ $br3: 3px; } svg { - fill: $color-black; - margin-right: 8px; - height: $size-3; - width: $size-3; + fill: $db-secondary; + margin-right: $s-8; + height: $s-12; + width: $s-12; } .element-title { color: $df-secondary; - font-size: $fs14; + font-size: $fs-14; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; @@ -390,42 +381,35 @@ $br3: 3px; &.recent-projects { svg { - fill: $color-white; + fill: $df-primary; } } - & .edit-wrapper { - border: 1px solid $color-gray-10; - border-radius: $br3; - display: flex; - width: 100%; - } - input.element-title { border: 0; - height: 30px; - padding: 5px; + height: $s-32; + padding: $s-6; margin: 0; width: 100%; - background-color: $color-white; + background-color: $df-primary; } .close { - background-color: $color-white; + background-color: $df-primary; cursor: pointer; - padding-left: 5px; + padding-left: $s-6; svg { - fill: $color-gray-30; - height: 15px; + fill: $df-secondary; + height: $s-16; transform: rotate(45deg) translateY(7px); - width: 15px; + width: $s-16; margin: 0; } } .element-subtitle { - color: $color-gray-20; + color: $df-secondary; font-style: italic; } @@ -446,11 +430,11 @@ $br3: 3px; align-items: center; cursor: pointer; display: flex; - padding: 10px 15px; + padding: $s-12 $s-16; position: relative; background-color: $db-tertiary; - border-top: 1px solid $db-cuaternary; + border-top: $s-1 solid $db-cuaternary; .profile { align-items: center; @@ -459,56 +443,56 @@ $br3: 3px; flex-grow: 1; span { - // @include text-ellipsis; + @include text-ellipsis; color: $df-primary; - margin: 10px; - font-size: $fs14; - max-width: 160px; + margin: $s-12; + font-size: $fs-14; + max-width: $s-160; } img { border-radius: 50%; flex-shrink: 0; - height: 25px; - width: 25px; + height: $s-40; + width: $s-40; } svg { - height: 10px; + height: $s-12; margin-left: auto; - margin-right: $size-2; - width: 10px; + margin-right: $s-8; + width: $s-12; } } .dropdown { - left: 15px; - bottom: 45px; + left: $s-16; + bottom: $s-44; - background-color: #212426; - border: 1px solid #2e3434; - border-radius: 8px; - min-width: 252px; + background-color: $db-primary; + border: $s-1 solid $db-tertiary; + border-radius: $br-8; + min-width: $s-252; - // @include animation(0, 0.2s, fadeInUp); + @include animation(0, 0.2s, fadeInUp); li { - font-size: $fs14; - padding: $size-2 $size-4; + font-size: $fs-14; + padding: $s-8 $s-16; svg { - fill: $color-gray-20; - margin-right: $size-2; + fill: $df-secondary; + margin-right: $s-8; - height: 12px; - width: 12px; + height: $s-12; + width: $s-12; } .text { - color: #ffffff; + color: $df-primary; } &.separator { - border-top: 1px solid transparent; + border-top: $s-1 solid transparent; } } } diff --git a/frontend/src/app/main/ui/dashboard/team.cljs b/frontend/src/app/main/ui/dashboard/team.cljs index dcb5cf8c2c..919675791d 100644 --- a/frontend/src/app/main/ui/dashboard/team.cljs +++ b/frontend/src/app/main/ui/dashboard/team.cljs @@ -678,7 +678,7 @@ [:span {:class (stl/css :rol-label)} label]]) [:& dropdown {:show @show? :on-close on-hide} - [:ul.dropdown.options-dropdown + [:ul {:class (stl/css :dropdown :options-dropdown)} [:li {:data-role "admin" :on-click on-change'} (tr "labels.admin")] [:li {:data-role "editor" :on-click on-change'} (tr "labels.editor")]]]] @@ -1148,12 +1148,6 @@ (mf/defc webhooks-hero {::mf/wrap-props false} [] - #_[:div.banner - [:div.title (tr "labels.webhooks") - [:div.description (tr "dashboard.webhooks.description")]] - [:div.create-container - [:div.create (tr "dashboard.webhooks.create")]]] - (let [new-css-system (mf/use-ctx ctx/new-css-system)] (if new-css-system [:div {:class (stl/css :webhooks-hero-container)} @@ -1478,4 +1472,3 @@ [:span.icon i/file-html] [:span.text (tr "labels.num-of-files" (i18n/c (:files stats)))]]]]]]]))) - diff --git a/frontend/src/app/main/ui/dashboard/team.scss b/frontend/src/app/main/ui/dashboard/team.scss index 9a1306770d..b8e3882a86 100644 --- a/frontend/src/app/main/ui/dashboard/team.scss +++ b/frontend/src/app/main/ui/dashboard/team.scss @@ -4,7 +4,590 @@ // // Copyright (c) KALEIDOS INC -@import "refactor/common-refactor.scss"; +@use "common/refactor/common-refactor.scss" as *; +@use "common/refactor/common-dashboard"; + +.dashboard-container { + flex: 1 0 0; + margin-right: $s-16; + overflow-y: auto; + width: 100%; + border-top: $s-1 solid $db-cuaternary; + + &.dashboard-projects { + user-select: none; + } + &.dashboard-shared { + width: calc(100vw - $s-320); + margin-right: $s-52; + } + + &.search { + margin-top: $s-12; + } +} + +.dashboard-team-webhooks { + display: flex; + flex-direction: column; + width: $s-800; + margin-left: $s-120; + margin-top: $s-80; + border: none; + align-items: flex-start; +} + +.webhooks-empty { + align-items: center; + background-color: transparent; + border-radius: $br-8; + border: $s-1 solid $db-cuaternary; + color: $df-secondary; + display: flex; + flex-direction: column; + font-size: $fs-12; + justify-content: center; + margin-top: $s-32; + max-width: $s-1000; + min-height: $s-136; + padding: $s-32; + text-align: center; + width: $s-468; +} + +.webhooks-hero-container { + max-width: $s-1000; + width: 100%; + display: flex; + flex-direction: column; + + width: $s-468; + background-color: transparent; + + .upload-button { + width: $s-100; + } + + .btn-secondary { + margin-left: $s-12; + } +} + +.webhooks-hero { + font-size: $fs-14; + display: flex; + flex-direction: column; + gap: $s-32; + justify-content: space-between; + margin-top: $s-32; + margin: 0; + padding: $s-32; + padding: 0; + width: $s-468; + + .desc { + color: $df-secondary; + width: 100%; + + h2 { + color: $df-primary; + font-size: $fs-24; + font-weight: regular; + margin-bottom: $s-32; + } + p { + color: $df-secondary; + margin-bottom: 0; + font-size: $fs-16; + } + } + .btn-primary { + flex-shrink: 0; + width: 100%; + font-size: $fs-12; + text-transform: uppercase; + background-color: $db-tertiary; + color: $df-primary; + &:hover { + color: $da-primary; + background-color: $db-cuaternary; + } + } +} + +.dropdown { + background-color: $db-tertiary; + border-radius: $br-8; + border: $s-1 solid $db-cuaternary; + box-shadow: 0 $s-2 $s-8 rgba(0, 0, 0, 0.25); + left: calc(-1 * $s-144); + max-height: $s-480; + min-width: $s-252; + overflow-y: auto; + position: absolute; + top: $s-32; + width: $s-152; + z-index: 12; + + hr { + margin: 0; + border-color: $df-secondary; + } + + li { + display: flex; + align-items: center; + cursor: pointer; + font-size: $fs-14; + padding: $s-4 $s-16; + border-radius: $br-8; + height: $s-40; + margin: $s-6; + color: $df-primary; + + &:hover { + background-color: $db-cuaternary; + } + + &.title { + font-weight: $fw700; + cursor: default; + } + } + + .separator { + border-color: transparent; + margin-top: $s-8; + } + + &.options-dropdown { + li { + color: $df-primary; + &.warning { + color: var(--warning-color); + } + } + } +} + +.dashboard-table { + display: flex; + flex-direction: column; + align-items: center; + margin-top: $s-20; + font-size: $fs-16; + + .table-header { + color: $df-secondary; + display: grid; + font-size: $fs-12; + grid-template-columns: 43% 1fr $s-108 $s-12; + height: $s-40; + max-width: $s-1000; + padding: 0 $s-16; + text-transform: uppercase; + user-select: none; + width: 100%; + } + .table-rows { + display: flex; + flex-direction: column; + max-width: $s-1000; + width: 100%; + margin-top: $s-16; + color: $db-secondary; + } + + .table-row { + align-items: center; + background-color: $db-tertiary; + border-radius: $br-8; + color: $df-primary; + display: flex; + height: $s-64; + padding: 0 $s-16; + width: 100%; + + &:not(:first-child) { + margin-top: $s-16; + } + } + + .table-field { + display: flex; + align-items: center; + + .icon { + padding-left: $s-12; + cursor: pointer; + } + + &.name { + width: 43%; + min-width: $s-300; + display: flex; + } + &.roles { + flex-grow: 1; + cursor: default; + position: relative; + .rol-label { + user-select: none; + } + .rol-selector { + &.has-priv { + cursor: pointer; + } + min-width: $s-160; + height: $s-32; + display: flex; + justify-content: space-between; + align-items: center; + padding: $s-4 $s-8; + font-size: $fs-14; + background-color: $db-cuaternary; + border-color: transparent; + border-radius: $br-8; + } + + .dropdown { + left: 0; + } + } + + &.actions { + position: relative; + .actions-dropdown { + max-height: $s-480; + min-width: $s-180; + } + + svg { + fill: $df-secondary; + } + } + + &.status { + .status-badge { + min-width: $s-76; + height: $s-24; + display: flex; + justify-content: center; + align-items: center; + border-radius: $br-8; + color: $db-primary; + text-transform: uppercase; + + &.pending { + background-color: var(--warning-color); + } + + &.expired { + background-color: $df-secondary; + } + + .status-label { + font-size: $fs-12; + } + } + } + + &.uri { + flex-grow: 1; + } + + &.active { + min-width: $s-100; + } + + &.last-delivery { + display: flex; + justify-content: center; + width: $s-52; + position: relative; + .success svg { + fill: $da-tertiary; + width: $s-16; + height: $s-16; + } + .failure svg { + fill: var(--warning-color); + width: $s-16; + height: $s-16; + } + + .icon-container { + width: $s-16; + height: $s-16; + overflow-x: visible; + } + + .icon { + padding: 0; + } + } + + .tooltip { + display: none; + position: absolute; + top: calc(-1 * $s-56); + left: 50%; + transform: translate(-50%, 0); + text-align: center; + + .label { + border-radius: $br-4; + color: $df-primary; + background-color: $db-secondary; + white-space: nowrap; + padding: $s-12 $s-20; + } + + .arrow-down { + margin: 0 auto; + width: 0; + height: 0; + border-left: $s-8 solid transparent; + border-right: $s-8 solid transparent; + border-top: $s-8 solid $db-secondary; + } + } + + .last-delivery-icon:hover { + .tooltip { + display: block; + } + } + } + + .member-info { + display: flex; + flex-direction: column; + margin-left: $s-16; + } + .member-name { + font-size: $fs-16; + } + .you { + color: $df-secondary; + margin-left: $s-6; + } + .member-email { + color: $df-secondary; + font-size: $fs-12; + } + .member-image { + height: $s-32; + width: $s-32; + img { + border-radius: 50%; + } + } + + .dashboard-team-webhooks & { + width: $s-800; + .table-rows { + padding-top: 0; + .table-row { + font-size: $fs-16; + min-height: $s-40; + height: fit-content; + .name { + color: $df-primary; + max-width: $s-480; + } + .expiration-date { + color: $df-secondary; + } + } + } + } + + &.team-members { + margin-bottom: $s-52; + } + + &.invitations { + .table-row { + display: grid; + grid-template-columns: 43% 1fr $s-108 $s-12; + } + } + + svg { + width: $s-12; + height: $s-12; + fill: $df-secondary; + } +} + +.empty-invitations { + height: $s-156; + max-width: $s-1000; + width: 100%; + display: flex; + justify-content: center; + align-items: center; + flex-direction: column; + margin-top: $s-16; + border: $s-1 solid $db-cuaternary; + border-radius: $br-8; + color: $df-secondary; +} + +.team-settings { + display: flex; + justify-content: center; + margin-top: $s-16; + + svg { + width: $s-20; + height: $s-20; + } + + .horizontal-blocks { + display: flex; + max-width: $s-1000; + justify-content: space-between; + width: 100%; + flex-direction: column; + gap: $s-24; + } + + .block { + display: flex; + max-width: $s-324; + width: $s-324; + flex-direction: column; + padding: $s-12; + + .label { + color: $df-secondary; + font-size: $fs-12; + text-transform: uppercase; + } + .icon svg { + fill: $df-secondary; + } + .name, + .text { + color: $df-primary; + } + } + + .info-block { + position: relative; + padding-top: $s-180; + + .name { + margin-top: $s-12; + font-size: $fs-24; + color: $df-primary; + @include text-ellipsis; + margin-right: $s-88; + } + + .icon { + position: absolute; + padding: $s-16; + right: 0; + top: 0; + left: 0; + height: $s-120; + width: $s-120; + + img { + border-radius: 50%; + width: $s-120; + height: $s-120; + } + + .update-overlay { + opacity: 0; + cursor: pointer; + position: absolute; + display: flex; + justify-content: center; + align-items: center; + border-radius: 50%; + color: $df-primary; + z-index: 14; + + background-color: $da-primary; + height: $s-120; + width: $s-120; + + svg { + fill: $db-primary; + } + } + + &:hover { + .update-overlay { + opacity: 1; + width: $s-72; + height: $s-72; + top: $s-16; + left: $s-16; + } + } + } + } + + .owner-block { + img { + width: $s-32; + height: $s-32; + border-radius: 50%; + } + + svg { + width: $s-12; + height: $s-12; + fill: $db-secondary; + } + + .owner { + margin-top: $s-6; + display: flex; + align-items: center; + color: $db-secondary; + .icon { + margin-right: $s-12; + } + } + + .summary { + margin-top: $s-6; + color: $db-secondary; + .icon { + padding: 0 $s-12; + margin-right: $s-12; + } + } + } + + .stats-block { + svg { + fill: $db-secondary; + } + + .projects, + .files { + margin-top: $s-8; + display: flex; + align-items: center; + color: $db-secondary; + + .icon { + display: flex; + align-items: center; + padding: 0 $s-2; + margin-right: $s-12; + } + } + } +} .modal-team-container { @extend .modal-container-base; @@ -140,1198 +723,3 @@ } } } - -///// - -@import "common/dependencies/colors"; - -$br2: 2px; -$br3: 3px; -$br4: 4px; -$br8: 8px; -$br6: 6px; -$br12: 12px; -$fs12: 0.75rem; -$fs13: 0.8125rem; -$fs14: 0.875rem; -$fs16: 1rem; -$fs18: 1.125rem; -$fs22: 1.375rem; -$fs24: 1.5rem; -$fs36: 2.25rem; -$fw400: 400; -$fw500: 500; -$fw600: 600; -$fw700: 700; -$lh-088: 0.88; -$lh-115: 1.15; // original $title-lh-sm -$lh-500: 5; // original $title-lh-sm -$size-1: 0.25rem; -$size-2: 0.5rem; -$size-4: 1rem; -$size-5: 1.5rem; -$size-6: 2rem; - -.dashboard-header { - display: flex; - align-items: center; - justify-content: space-between; - background-color: $color-white; - height: 63px; - padding: $size-1 $size-4 $size-1 $size-2; - position: relative; - z-index: 10; - user-select: none; - &.team { - display: grid; - grid-template-columns: 20% 1fr 20%; - } - - .element-name { - margin-right: $size-2; - } - - .btn-secondary { - flex-shrink: 0; - z-index: 10; - height: 32px; - } - - svg { - fill: $color-black; - height: 14px; - margin-right: $size-1; - width: 14px; - } - - nav { - display: flex; - align-items: flex-end; - justify-content: center; - z-index: 1; - - ul { - display: flex; - font-size: $fs14; - justify-content: center; - margin: 0; - } - - li { - a { - display: flex; - align-items: center; - flex-basis: 140px; - border-bottom: 3px solid transparent; - color: $color-gray-30; - height: 40px; - padding: $size-1 $size-5; - font-weight: $fw400; - &:hover { - color: $color-black; - text-decoration: none; - } - } - - //&.active { - // a { - // color: $color-black; - // border-color: $color-primary; - // } - //} - } - } - - .dashboard-title { - display: flex; - align-items: center; - margin-left: 13px; - - h1 { - color: $color-black; - display: flex; - flex-shrink: 0; - font-size: $fs22; - font-weight: $fw600; - z-index: 10; - user-select: all; - } - - .context-menu.is-open { - margin-top: 10px; - } - } - - .icon { - display: flex; - align-items: center; - cursor: pointer; - margin-left: $size-2; - z-index: 10; - - svg { - fill: $color-gray-40; - width: 15px; - height: 15px; - - &:hover { - fill: $color-primary-dark; - } - } - } - - .dashboard-buttons { - display: flex; - justify-content: flex-end; - align-items: center; - } - - .dashboard-header-actions { - display: flex; - } - - .pin-icon { - margin: 0 $size-2 0 $size-5; - background-color: transparent; - border: none; - svg { - fill: $color-gray-20; - } - - &.active { - svg { - fill: $color-gray-50; - } - } - } -} - -.dashboard-header { - background-color: transparent; - .dashboard-title { - h1 { - color: $df-primary; - font-size: 24px; - font-weight: 400; - width: 100%; - text-overflow: ellipsis; - overflow: hidden; - white-space: nowrap; - display: block; - max-width: 700px; - } - } - .icon { - svg { - fill: $df-secondary; - } - } - - // Settings sub-menu - .dashboard-header-options { - li { - a { - font-size: 16px; - color: $df-secondary; - border-color: transparent; - &:hover { - color: $df-primary; - } - } - &.active { - a { - color: $df-primary; - } - } - } - } -} - -.dashboard-container { - background-color: $color-dashboard; - flex: 1 0 0; - margin-right: $size-4; - overflow-y: auto; - width: 100%; - &.dashboard-projects { - user-select: none; - } - &.no-bg { - background-color: transparent; - } - &.dashboard-shared { - width: calc(100vw - 320px); - margin-right: 50px; - } - - &.search { - margin-top: 10px; - } -} - -.dashboard-container { - background-color: transparent; - border-top: 1px solid $db-cuaternary; - - .dashboard-settings { - a { - color: $df-secondary; - } - .form-container { - width: 800px; - margin: 80px auto auto 120px; - form { - width: 468px; - .fields-row { - .custom-input, - .custom-select { - flex-direction: column-reverse; - label { - position: relative; - text-transform: uppercase; - color: $df-primary; - font-size: 11px; - margin-bottom: 12px; - margin-left: -4px; - } - input, - select { - background-color: $db-tertiary; - border-radius: 8px; - border-color: transparent; - color: $df-primary; - padding: 0 15px; - &:focus { - outline: 1px solid $da-primary; - } - ::placeholder { - color: $df-secondary; - } - } - .help-icon { - bottom: 12px; - top: auto; - svg { - fill: $df-secondary; - } - } - &.disabled { - input { - background-color: $db-primary; - border-color: $db-cuaternary; - color: $df-secondary; - } - } - .input-container { - background-color: $db-tertiary; - border-radius: 8px; - border-color: transparent; - margin-top: 22px; - .main-content { - label { - position: absolute; - top: -24px; - } - span { - color: $df-primary; - } - } - &:focus { - border: 1px solid $da-primary; - } - } - textarea { - border-radius: 8px; - padding: 12px 14px; - background-color: $db-tertiary; - color: $df-primary; - border: none; - &:focus { - outline: 1px solid $da-primary; - } - } - } - } - .field-title { - color: $df-primary; - } - .field-title:not(:first-child) { - margin-top: 64px; - } - - .field-text { - color: $df-secondary; - } - button, - .btn-secondary { - width: 100%; - font-size: 11px; - text-transform: uppercase; - background-color: $db-tertiary; - color: $df-primary; - &:hover { - color: $da-primary; - background-color: $db-cuaternary; - } - } - hr { - display: none; - } - } - .links { - margin-top: 12px; - } - } - } - - //Access tokens - .dashboard-access-tokens { - width: 800px; - margin-left: 120px; - margin-top: 80px; - .access-tokens-hero-container { - background-color: transparent; - .access-tokens-hero { - width: 468px; - flex-direction: column; - gap: 32px; - background-color: transparent; - margin: 0; - padding: 0; - .desc { - background-color: transparent; - width: 100%; - h2 { - color: $df-primary; - font-size: 24px; - font-weight: regular; - margin-bottom: 32px; - } - p { - color: $df-secondary; - margin-bottom: 0; - font-size: 14px; - } - } - button { - width: 100%; - font-size: 11px; - text-transform: uppercase; - background-color: $db-tertiary; - color: $df-primary; - &:hover { - color: $da-primary; - background-color: $db-cuaternary; - } - } - } - } - .dashboard-table { - width: 800px; - .table-rows { - padding-top: 0; - .table-row { - font-size: 14px; - min-height: 40px; - height: fit-content; - .name { - color: $df-primary; - max-width: 480px; - overflow: hidden; - text-overflow: ellipsis; - display: -webkit-box; - -webkit-line-clamp: 2; - -webkit-box-orient: vertical; - } - .expiration-date { - color: $df-secondary; - } - } - } - } - .access-tokens-empty { - width: 468px; - border: 1px solid $db-cuaternary; - border-radius: 8px; - margin-top: 32px; - font-size: 14px; - background-color: transparent; - color: $df-secondary; - } - } - - // Team webhooks - &.dashboard-team-webhooks { - width: 800px; - margin-left: 120px; - margin-top: 80px; - border: none; - align-items: flex-start; - .webhooks-hero-container { - width: 468px; - background-color: transparent; - .webhooks-hero { - width: 468px; - flex-direction: column; - gap: 32px; - background-color: transparent; - margin: 0; - padding: 0; - .desc { - background-color: transparent; - width: 100%; - h2 { - color: $df-primary; - font-size: 24px; - font-weight: regular; - margin-bottom: 32px; - } - p { - color: $df-secondary; - margin-bottom: 0; - font-size: 14px; - } - } - .btn-primary { - width: 100%; - font-size: 11px; - text-transform: uppercase; - background-color: $db-tertiary; - color: $df-primary; - &:hover { - color: $da-primary; - background-color: $db-cuaternary; - } - } - } - } - .dashboard-table { - width: 800px; - .table-rows { - padding-top: 0; - .table-row { - font-size: 14px; - min-height: 40px; - height: fit-content; - .name { - color: $df-primary; - max-width: 480px; - } - .expiration-date { - color: $df-secondary; - } - } - } - } - .webhooks-empty { - width: 468px; - border: 1px solid $db-cuaternary; - border-radius: 8px; - margin-top: 32px; - font-size: 14px; - background-color: transparent; - color: $df-secondary; - } - } - - // Members section - .dashboard-table { - .table-header { - background-color: transparent; - color: $df-secondary; - font-size: 12px; - text-transform: uppercase; - } - .table-rows { - .table-row { - background-color: $db-tertiary; - border-radius: 8px; - color: $df-primary; - .rol-selector { - background-color: $db-cuaternary; - border-color: transparent; - border-radius: 8px; - } - } - } - .member-info { - .member-name .you, - .member-email { - color: $df-secondary; - } - } - .status-badge { - border-radius: 8px; - color: $db-primary; - text-transform: uppercase; - } - .empty-invitations { - border: 1px solid $db-cuaternary; - border-radius: 8px; - color: $df-secondary; - } - } - .actions-dropdown, - .options-dropdown { - background-color: $db-tertiary; - border: 1px solid $db-cuaternary; - border-radius: 8px; - min-width: 252px; - - .separator { - border-color: transparent; - margin-top: 10px; - } - - li { - border-radius: 8px; - height: 40px; - margin: 5px; - color: $df-primary; - - &:hover { - background-color: $db-cuaternary; - } - } - - &.options-dropdown { - li { - color: $df-primary; - &.warning { - color: $color-danger; - } - } - } - } -} - -.dashboard-table { - display: flex; - flex-direction: column; - align-items: center; - margin-top: 20px; - font-size: $fs16; - - &.team-members { - margin-bottom: 52px; - } - - &.invitations { - .table-row { - display: grid; - grid-template-columns: 43% 1fr 109px 12px; - } - } - - .table-header { - display: grid; - grid-template-columns: 43% 1fr 109px 12px; - max-width: 1040px; - background-color: $color-white; - color: $color-gray-30; - width: 100%; - height: 40px; - padding: 0px 16px; - } - - .table-rows { - display: flex; - flex-direction: column; - max-width: 1040px; - width: 100%; - margin-top: 16px; - color: $color-black; - } - - .table-row { - display: flex; - width: 100%; - height: 45px; - align-items: center; - padding: 0px 16px; - } - - .table-field { - display: flex; - align-items: center; - - .icon { - padding-left: 10px; - cursor: pointer; - } - } - - svg { - width: 10px; - height: 10px; - fill: $color-black; - } -} - -.dashboard-team-members, -.dashboard-team-invitations, -.dashboard-team-webhooks { - .empty-invitations { - height: 156px; - max-width: 1040px; - width: 100%; - display: flex; - justify-content: center; - align-items: center; - flex-direction: column; - border: 1px dashed $color-gray-20; - margin-top: 16px; - } - .table-header { - user-select: none; - } - - .table-row { - background-color: $color-white; - height: 63px; - &:not(:first-child) { - margin-top: 16px; - } - } - - .table-field { - &.name { - width: 43%; - min-width: 300px; - display: flex; - .member-info { - display: flex; - flex-direction: column; - margin-left: 16px; - .member-name { - font-size: $fs16; - .you { - color: $color-gray-30; - margin-left: 5px; - } - } - .member-email { - color: $color-gray-30; - font-size: $fs12; - } - } - - .member-image { - height: 32px; - width: 32px; - img { - border-radius: 50%; - } - } - } - - &.roles { - flex-grow: 1; - cursor: default; - position: relative; - .rol-label { - user-select: none; - } - .rol-selector { - &.has-priv { - border: 1px solid $color-gray-20; - cursor: pointer; - } - min-width: 160px; - height: 32px; - display: flex; - justify-content: space-between; - align-items: center; - border-radius: $br2; - padding: 3px 8px; - font-size: $fs14; - } - } - - &.actions { - position: relative; - .actions-dropdown { - max-height: 30rem; - min-width: 180px; - } - - svg { - fill: $df-secondary; - } - } - - &.status { - .status-badge { - color: $color-white; - border-radius: $br12; - min-width: 74px; - height: 24px; - display: flex; - justify-content: center; - align-items: center; - - &.pending { - background-color: $color-warning; - } - - &.expired { - background-color: $color-gray-20; - } - - .status-label { - font-size: $fs12; - } - } - } - - &.uri { - flex-grow: 1; - } - - &.active { - min-width: 100px; - } - - &.last-delivery { - display: flex; - justify-content: center; - width: 50px; - position: relative; - .success svg { - fill: $color-primary; - width: 16px; - height: 16px; - } - .failure svg { - fill: $color-warning; - width: 16px; - height: 16px; - } - - .icon-container { - width: 16px; - height: 16px; - overflow-x: visible; - } - - .icon { - padding: 0; - } - } - - .tooltip { - display: none; - position: absolute; - top: -58px; - left: 50%; - transform: translate(-50%, 0); - text-align: center; - - .label { - border-radius: $br3; - color: $color-white; - background-color: $color-black; - white-space: nowrap; - padding: 12px 20px; - } - - .arrow-down { - margin: 0 auto; - width: 0; - height: 0; - border-left: 8px solid transparent; - border-right: 8px solid transparent; - border-top: 8px solid $color-black; - } - } - - .last-delivery-icon:hover { - .tooltip { - display: block; - } - } - } - - .dropdown { - position: absolute; - max-height: 30rem; - overflow-y: auto; - background-color: $color-white; - border-radius: $br4; - box-shadow: 0px 2px 8px rgba(0, 0, 0, 0.25); - z-index: 12; - top: 30px; - left: -151px; - width: 155px; - - hr { - margin: 0; - border-color: $color-gray-10; - } - - li { - display: flex; - align-items: center; - color: $color-gray-60; - cursor: pointer; - font-size: $fs14; - height: 31px; - padding: 5px 16px; - - &.title { - font-weight: $fw600; - cursor: default; - } - - &:hover { - background-color: $color-primary-lighter; - } - } - } -} - -.dashboard-team-settings { - .team-settings { - display: flex; - justify-content: center; - margin-top: 16px; - - svg { - width: 20px; - height: 20px; - } - - .horizontal-blocks { - display: flex; - max-width: 1010px; - justify-content: space-between; - width: 100%; - } - - .block { - display: flex; - max-width: 324px; - width: 324px; - background-color: $color-white; - flex-direction: column; - padding: 12px; - - .label { - font-size: $fs13; - color: $color-gray-30; - } - } - - .info-block { - position: relative; - - .name { - margin-top: 10px; - font-size: $fs24; - color: $color-black; - @include text-ellipsis; - margin-right: 90px; - } - - .icon { - position: absolute; - padding: 15px; - width: 100px; - height: 100px; - right: 0px; - top: 0px; - - img { - border-radius: 50%; - width: 70px; - height: 70px; - } - - .update-overlay { - opacity: 0; - cursor: pointer; - position: absolute; - display: flex; - justify-content: center; - align-items: center; - width: 71px; - height: 71px; - border-radius: 50%; - color: $color-white; - background: $color-primary-dark; - z-index: 14; - - svg { - fill: $color-white; - } - } - - &:hover { - .update-overlay { - opacity: 1; - width: 72px; - height: 72px; - top: 14px; - left: 14px; - } - } - } - } - - .owner-block { - img { - width: 30px; - height: 30px; - border-radius: 50%; - } - - svg { - width: 12px; - height: 12px; - fill: $color-black; - } - - .owner { - margin-top: 5px; - display: flex; - align-items: center; - color: $color-black; - .icon { - margin-right: 12px; - } - } - - .summary { - margin-top: 5px; - color: $color-black; - .icon { - padding: 0px 10px; - margin-right: 12px; - } - } - } - - .stats-block { - svg { - fill: $color-black; - } - - .projects, - .files { - margin-top: 7px; - display: flex; - align-items: center; - color: $color-black; - - .icon { - display: flex; - align-items: center; - padding: 0px 2px; - margin-right: 14px; - } - } - } - } -} - -.dashboard-team-webhooks { - display: flex; - flex-direction: column; - align-items: center; - - .webhooks-hero-container { - max-width: 1000px; - width: 100%; - display: flex; - flex-direction: column; - - .upload-button { - width: 100px; - } - - .btn-secondary { - margin-left: 10px; - } - } - - .webhooks-hero { - font-size: $fs14; - - padding: $size-6; - background-color: $color-white; - margin-top: $size-6; - display: flex; - justify-content: space-between; - - .banner { - background-color: unset; - - display: flex; - - .icon { - display: flex; - align-items: center; - padding-left: 0px; - padding-right: 10px; - svg { - fill: $color-info; - } - } - } - - .desc { - h2 { - margin-bottom: $size-4; - color: $color-black; - } - width: 80%; - color: $color-gray-40; - p { - font-size: $fs16; - } - } - - .btn-primary { - flex-shrink: 0; - } - } - - .webhooks-empty { - text-align: center; - max-width: 1000px; - width: 100%; - padding: $size-6; - display: flex; - flex-direction: column; - justify-content: center; - align-items: center; - border: 1px dashed $color-gray-20; - color: $color-gray-40; - margin-top: 12px; - min-height: 136px; - } -} - -.webhooks-modal { - .action-buttons { - gap: 10px; - - .cancel-button { - border: 1px solid $color-gray-30; - background: $color-canvas; - border-radius: $br3; - padding: 0.5rem 1rem; - cursor: pointer; - margin-right: 8px; - - &:hover { - background: $color-gray-20; - } - } - } - .input-checkbox label { - font-size: $fs14; - color: $color-black; - } - - .explain { - font-size: $fs12; - color: $color-gray-40; - } -} - -.dashboard-team-settings { - .team-settings { - .horizontal-blocks { - flex-direction: column; - gap: 24px; - .block { - background-color: transparent; - .label { - color: $df-secondary; - font-size: 11px; - text-transform: uppercase; - } - .icon { - svg { - fill: $df-secondary; - } - } - .name, - .text { - color: $df-primary; - } - &.info-block { - padding-top: 180px; - .icon { - left: 0; - height: 120px; - width: 120px; - img { - width: 120px; - height: 120px; - } - .update-overlay { - background-color: $da-primary; - height: 120px; - width: 120px; - svg { - fill: $db-primary; - } - } - } - } - } - } - } -} - -.btn-secondary { - background-color: $db-tertiary; - text-transform: uppercase; - border: none; - color: $df-primary; - border-radius: 8px; - - font-size: 0.75rem; - padding: 0 1rem; - cursor: pointer; - display: flex; - justify-content: center; - align-items: center; - - &:hover { - background-color: $db-cuaternary; - color: $da-primary; - text-decoration: none; - svg { - fill: $da-primary; - } - } -} - -.btn-primary { - background-color: $da-tertiary; - border-radius: 8px; - color: $db-primary; - height: 32px; - text-transform: uppercase; - - appearance: none; - align-items: center; - border: none; - cursor: pointer; - display: flex; - font-family: "worksans", sans-serif; - font-size: $fs12; - justify-content: center; - min-width: 25px; - padding: 0 1rem; - transition: all 0.4s; - text-decoration: none; - - &:hover { - background-color: darken($da-tertiary, 10%); - color: $db-primary; - } -} diff --git a/frontend/src/app/main/ui/dashboard/templates.scss b/frontend/src/app/main/ui/dashboard/templates.scss index 8f6ba747f2..9a62effef8 100644 --- a/frontend/src/app/main/ui/dashboard/templates.scss +++ b/frontend/src/app/main/ui/dashboard/templates.scss @@ -4,18 +4,7 @@ // // Copyright (c) KALEIDOS INC -@import "common/dependencies/colors"; - -$br10: 10px; -$lh-normal: normal; -$fs18: 1.125rem; -$fw600: 600; -$fs16: 1rem; -$br5: 5px; -$fw500: 500; -$fs14: 0.875rem; -$fs12: 0.75rem; -$size-2: 0.5rem; +@use "common/refactor/common-refactor.scss" as *; .dashboard-templates-section { position: absolute; @@ -24,54 +13,53 @@ $size-2: 0.5rem; justify-content: flex-end; bottom: 0; width: 100%; - height: 228px; + height: $s-228; transition: bottom 300ms; pointer-events: none; &.collapsed { - bottom: -228px; + bottom: calc(-1 * $s-228); transition: bottom 300ms; } .title { pointer-events: all; width: fit-content; - top: -56px; - right: -28px; + top: calc(-1 * $s-56); text-align: right; - height: 56px; + height: $s-56; position: absolute; + right: calc(-1 * $s-24); + button { border: none; cursor: pointer; - height: 58px; + height: $s-56; display: inline-flex; align-items: center; - border-top: 2px solid #e4e4e4; - border-left: 2px solid #e4e4e4; - border-right: 2px solid #e4e4e4; - border-top-left-radius: $br10; - border-top-right-radius: $br10; - margin-right: 30px; - background-color: $color-white; + border-top-left-radius: $br-10; + border-top-right-radius: $br-10; + margin-right: $s-32; position: relative; z-index: 1; + background-color: $db-cuaternary; + span { display: inline-block; vertical-align: middle; - line-height: $lh-normal; - font-size: $fs18; - font-weight: $fw600; - color: $color-black; - margin-left: 18px; - margin-right: 10px; + line-height: 1.2; + font-size: $fs-16; + margin-left: $s-16; + margin-right: $s-8; + color: $df-primary; + font-weight: $fw400; &.icon { - margin-left: 10px; - margin-right: 16px; + margin-left: $s-16; + margin-right: $s-16; } } svg { - width: 12px; - height: 12px; + width: $s-12; + height: $s-12; fill: $df-secondary; } } @@ -79,52 +67,51 @@ $size-2: 0.5rem; .button { position: absolute; - top: 133px; - border: 2px solid #e0e4e9; + top: $s-136; + border: $s-2 solid $df-secondary; border-radius: 50%; text-align: center; - width: 35px; - height: 35px; + width: $s-36; + height: $s-36; cursor: pointer; - background-color: $color-white; + background-color: $df-primary; display: flex; align-items: center; justify-content: center; pointer-events: all; svg { - width: 12px; - height: 12px; + width: $s-12; + height: $s-12; fill: $df-secondary; } &.left { left: 0; - margin-left: 43px; + margin-left: $s-44; } &.right { right: 0; - margin-right: 43px; + margin-right: $s-44; } &:hover { - border: 2px solid $color-primary; + border: $s-2 solid $da-tertiary; } } .content { pointer-events: all; - background-color: $color-white; width: 200%; - height: 229px; - border-top: 2px solid #e4e4e4; - border-left: 2px solid #e4e4e4; - margin-left: 5px; + height: $s-228; + margin-left: $s-6; position: absolute; + border-top-left-radius: $s-8; + background-color: $db-cuaternary; .card-container { - width: 275px; - margin-top: 20px; + width: $s-276; + margin-top: $s-20; display: inline-block; text-align: center; vertical-align: top; @@ -135,111 +122,69 @@ $size-2: 0.5rem; .template-card { display: inline-block; - width: 255px; - font-size: $fs16; - color: #181a22; + width: $s-256; + font-size: $fs-16; cursor: pointer; + color: $df-primary; + padding: $s-3 $s-6 $s-16 $s-6; + border-radius: $br-8; + .img-container { width: 100%; - height: 135px; - margin-bottom: 15px; - border-radius: $br5; - border: 2px solid #e0e4e9; + height: $s-136; + margin-bottom: $s-16; + border-radius: $br-5; display: flex; justify-content: center; flex-direction: column; + + img { + border-radius: $br-4; + } } .card-name { - padding: 0 5px; + padding: 0 $s-6; display: flex; justify-content: space-between; - height: 23px; + height: $s-24; + align-items: center; + + .icon { + width: $s-16; + height: $s-16; + } svg { - width: 16px; - height: 16px; + width: $s-16; + height: $s-16; fill: $df-secondary; } span { font-weight: $fw500; - font-size: $fs14; + font-size: $fs-16; } } .template-link { - border: 2px solid transparent; - margin: 30px; - padding: 32px 0; + border: $s-2 solid transparent; + margin: $s-32; + padding: $s-32 0; } .template-link-title { - font-size: $fs14; - font-weight: $fw600; - color: $color-gray-60; + font-size: $fs-14; + color: $df-primary; + font-weight: $fw400; } .template-link-text { - font-size: $fs12; - margin-top: $size-2; - color: $color-gray-50; - } - - &:hover { - .img-container { - border: 2px solid $color-primary; - } - } - } - } -} - -.dashboard-templates-section { - .title { - right: -24px; - button { - background-color: $db-cuaternary; - border: none; - span { - color: $df-primary; - font-weight: 400; - } - } - } - .content { - border-top-left-radius: 8px; - border: none; - background-color: $db-cuaternary; - - .template-card { - color: $df-primary; - padding: 0.2rem 0.3rem 1rem 0.3rem; - border-radius: 8px; - .img-container { - border: none; - img { - border-radius: 4px; - } - } - .card-name { - span { - font-size: 16px; - } - } - .template-link { - .template-link-title { - color: $df-primary; - font-weight: 400; - } - .template-link-text { - color: $df-secondary; - } + font-size: $fs-12; + margin-top: $s-8; + color: $df-secondary; } &:hover { background-color: $db-tertiary; - .img-container { - border: none; - } } } } diff --git a/frontend/src/app/main/ui/settings.cljs b/frontend/src/app/main/ui/settings.cljs index 7fdcaef887..946f6f1c6c 100644 --- a/frontend/src/app/main/ui/settings.cljs +++ b/frontend/src/app/main/ui/settings.cljs @@ -7,9 +7,11 @@ (ns app.main.ui.settings (:require-macros [app.main.style :as stl]) (:require + [app.main.data.dashboard.shortcuts :as sc] [app.main.refs :as refs] [app.main.store :as st] [app.main.ui.context :as ctx] + [app.main.ui.hooks :as hooks] [app.main.ui.settings.access-tokens :refer [access-tokens-page]] [app.main.ui.settings.change-email] [app.main.ui.settings.delete-account] @@ -44,6 +46,8 @@ profile (mf/deref refs/profile) locale (mf/deref i18n/locale)] + (hooks/use-shortcuts ::dashboard sc/shortcuts) + (mf/use-effect #(when (nil? profile) (st/emit! (rt/nav :auth-login)))) diff --git a/frontend/src/app/main/ui/settings.scss b/frontend/src/app/main/ui/settings.scss index 2f907fb3fd..e295be303b 100644 --- a/frontend/src/app/main/ui/settings.scss +++ b/frontend/src/app/main/ui/settings.scss @@ -1,23 +1,11 @@ -@import "common/dependencies/colors"; +// 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 -$fs14: 0.875rem; -$fs22: 1.5rem; -$fs24: 1.5rem; -$lh-500: 5; -$fs12: 0.75rem; -$fs16: 1rem; -$fw400: 400; -$fw600: 600; -$size-1: 0.25rem; -$size-2: 0.5rem; -$size-3: 0.75rem; -$size-4: 1rem; -$size-5: 1.5rem; -$size-6: 2rem; -$br3: 3px; -$br4: 4px; -$br5: 5px; -$fw700: 700; +@use "common/refactor/common-refactor.scss" as *; +@use "common/refactor/common-dashboard"; .dashboard { background-color: $db-primary; @@ -35,540 +23,23 @@ $fw700: 700; padding: 1rem 1rem 0 0; } -.dashboard-header { - display: flex; - align-items: center; - justify-content: space-between; - background-color: $color-white; - height: 63px; - padding: $size-1 $size-4 $size-1 $size-2; - position: relative; - z-index: 10; - user-select: none; - &.team { - display: grid; - grid-template-columns: 20% 1fr 20%; - } - - .element-name { - margin-right: $size-2; - } - - .btn-secondary { - flex-shrink: 0; - z-index: 10; - height: 32px; - svg { - height: 16px; - width: 16px; - } - } - - svg { - fill: $color-black; - height: 14px; - margin-right: $size-1; - width: 14px; - } - - nav { - display: flex; - align-items: flex-end; - justify-content: center; - z-index: 1; - - ul { - display: flex; - font-size: $fs14; - justify-content: center; - margin: 0; - } - - li { - a { - display: flex; - align-items: center; - flex-basis: 140px; - border-bottom: 3px solid transparent; - color: $color-gray-30; - height: 40px; - padding: $size-1 $size-5; - font-weight: $fw400; - &:hover { - color: $color-black; - text-decoration: none; - } - } - - &.active { - a { - color: $color-black; - border-color: $color-primary; - } - } - } - } - - .dashboard-title { - display: flex; - align-items: center; - margin-left: 13px; - - h1 { - color: $color-black; - display: flex; - flex-shrink: 0; - font-size: $fs22; - font-weight: $fw600; - z-index: 10; - user-select: all; - } - - .context-menu.is-open { - margin-top: 10px; - } - } - - .icon { - display: flex; - align-items: center; - cursor: pointer; - margin-left: $size-2; - z-index: 10; - - svg { - fill: $color-gray-40; - width: 15px; - height: 15px; - - &:hover { - fill: $color-primary-dark; - } - } - } - - .dashboard-buttons { - display: flex; - justify-content: flex-end; - align-items: center; - } - - .dashboard-header-actions { - display: flex; - } - - .pin-icon { - margin: 0 $size-2 0 $size-5; - background-color: transparent; - border: none; - svg { - fill: $color-gray-20; - } - - &.active { - svg { - fill: $color-gray-50; - } - } - } -} - -.dashboard-header { - background-color: transparent; - .dashboard-title { - h1 { - color: $df-primary; - font-size: 24px; - font-weight: 400; - width: 100%; - text-overflow: ellipsis; - overflow: hidden; - white-space: nowrap; - display: block; - max-width: 700px; - } - } - .icon { - svg { - fill: $df-secondary; - } - } - - // Settings sub-menu - .dashboard-header-options { - li { - a { - font-size: 16px; - color: $df-secondary; - border-color: transparent; - &:hover { - color: $df-primary; - } - } - &.active { - a { - color: $df-primary; - } - } - } - } -} - .dashboard-container { - background-color: $color-dashboard; flex: 1 0 0; - margin-right: $size-4; + margin-right: $s-16; overflow-y: auto; width: 100%; + border-top: $s-1 solid $db-cuaternary; + &.dashboard-projects { user-select: none; } - &.no-bg { - background-color: transparent; - } &.dashboard-shared { - width: calc(100vw - 320px); - margin-right: 50px; + width: calc(100vw - $s-320); + margin-right: $s-52; } &.search { - margin-top: 10px; - } -} - -.dashboard-container { - background-color: transparent; - border-top: 1px solid $db-cuaternary; - - .dashboard-settings { - a { - color: $df-secondary; - } - .form-container { - width: 800px; - margin: 80px auto auto 120px; - form { - width: 468px; - .fields-row { - .custom-input, - .custom-select { - flex-direction: column-reverse; - label { - position: relative; - text-transform: uppercase; - color: $df-primary; - font-size: 11px; - margin-bottom: 12px; - margin-left: -4px; - } - input, - select { - background-color: $db-tertiary; - border-radius: 8px; - border-color: transparent; - color: $df-primary; - padding: 0 15px; - &:focus { - outline: 1px solid $da-primary; - } - ::placeholder { - color: $df-secondary; - } - } - .help-icon { - bottom: 12px; - top: auto; - svg { - fill: $df-secondary; - } - } - &.disabled { - input { - background-color: $db-primary; - border-color: $db-cuaternary; - color: $df-secondary; - } - } - .input-container { - background-color: $db-tertiary; - border-radius: 8px; - border-color: transparent; - margin-top: 22px; - .main-content { - label { - position: absolute; - top: -24px; - } - span { - color: $df-primary; - } - } - &:focus { - border: 1px solid $da-primary; - } - } - textarea { - border-radius: 8px; - padding: 12px 14px; - background-color: $db-tertiary; - color: $df-primary; - border: none; - &:focus { - outline: 1px solid $da-primary; - } - } - } - } - .field-title { - color: $df-primary; - } - .field-title:not(:first-child) { - margin-top: 64px; - } - - .field-text { - color: $df-secondary; - } - button, - .btn-secondary { - width: 100%; - font-size: 11px; - text-transform: uppercase; - background-color: $db-tertiary; - color: $df-primary; - &:hover { - color: $da-primary; - background-color: $db-cuaternary; - } - } - hr { - display: none; - } - } - .links { - margin-top: 12px; - } - } - } - - //Access tokens - .dashboard-access-tokens { - width: 800px; - margin-left: 120px; - margin-top: 80px; - .access-tokens-hero-container { - background-color: transparent; - .access-tokens-hero { - width: 468px; - flex-direction: column; - gap: 32px; - background-color: transparent; - margin: 0; - padding: 0; - .desc { - background-color: transparent; - width: 100%; - h2 { - color: $df-primary; - font-size: 24px; - font-weight: regular; - margin-bottom: 32px; - } - p { - color: $df-secondary; - margin-bottom: 0; - font-size: 14px; - } - } - button { - width: 100%; - font-size: 11px; - text-transform: uppercase; - background-color: $db-tertiary; - color: $df-primary; - &:hover { - color: $da-primary; - background-color: $db-cuaternary; - } - } - } - } - .dashboard-table { - width: 800px; - .table-rows { - padding-top: 0; - .table-row { - font-size: 14px; - min-height: 40px; - height: fit-content; - .name { - color: $df-primary; - max-width: 480px; - overflow: hidden; - text-overflow: ellipsis; - display: -webkit-box; - -webkit-line-clamp: 2; - -webkit-box-orient: vertical; - } - .expiration-date { - color: $df-secondary; - } - } - } - } - .access-tokens-empty { - width: 468px; - border: 1px solid $db-cuaternary; - border-radius: 8px; - margin-top: 32px; - font-size: 14px; - background-color: transparent; - color: $df-secondary; - } - } - - // Team webhooks - &.dashboard-team-webhooks { - width: 800px; - margin-left: 120px; - margin-top: 80px; - border: none; - align-items: flex-start; - .webhooks-hero-container { - width: 468px; - background-color: transparent; - .webhooks-hero { - width: 468px; - flex-direction: column; - gap: 32px; - background-color: transparent; - margin: 0; - padding: 0; - .desc { - background-color: transparent; - width: 100%; - h2 { - color: $df-primary; - font-size: 24px; - font-weight: regular; - margin-bottom: 32px; - } - p { - color: $df-secondary; - margin-bottom: 0; - font-size: 14px; - } - } - .btn-primary { - width: 100%; - font-size: 11px; - text-transform: uppercase; - background-color: $db-tertiary; - color: $df-primary; - &:hover { - color: $da-primary; - background-color: $db-cuaternary; - } - } - } - } - .dashboard-table { - width: 800px; - .table-rows { - padding-top: 0; - .table-row { - font-size: 14px; - min-height: 40px; - height: fit-content; - .name { - color: $df-primary; - max-width: 480px; - } - .expiration-date { - color: $df-secondary; - } - } - } - } - .webhooks-empty { - width: 468px; - border: 1px solid $db-cuaternary; - border-radius: 8px; - margin-top: 32px; - font-size: 14px; - background-color: transparent; - color: $df-secondary; - } - } - - // Members section - .dashboard-table { - .table-header { - background-color: transparent; - color: $df-secondary; - font-size: 12px; - text-transform: uppercase; - } - .table-rows { - .table-row { - background-color: $db-tertiary; - border-radius: 8px; - color: $df-primary; - .rol-selector { - background-color: $db-cuaternary; - border-color: transparent; - border-radius: 8px; - } - } - } - .member-info { - .member-name .you, - .member-email { - color: $df-secondary; - } - } - .status-badge { - border-radius: 8px; - color: $db-primary; - text-transform: uppercase; - } - .empty-invitations { - border: 1px solid $db-cuaternary; - border-radius: 8px; - color: $df-secondary; - } - } - .actions-dropdown, - .options-dropdown { - background-color: $db-tertiary; - border: 1px solid $db-cuaternary; - border-radius: 8px; - min-width: 252px; - - .separator { - border-color: transparent; - margin-top: 10px; - } - - li { - border-radius: 8px; - height: 40px; - margin: 5px; - color: $df-primary; - - &:hover { - background-color: $db-cuaternary; - } - } - - &.options-dropdown { - li { - color: $df-primary; - &.warning { - color: $color-danger; - } - } - } + margin-top: $s-12; } } @@ -577,121 +48,226 @@ $fw700: 700; width: 100%; justify-content: center; align-items: center; + a { + color: $df-secondary; + } +} - .form-container { - margin-top: 50px; - display: flex; - max-width: 368px; - margin-bottom: 2rem; - width: 100%; +.form-container { + width: 800px; + margin: 50px auto 2rem 120px; + display: flex; + max-width: 368px; + width: 100%; - &.two-columns { - max-width: 536px; - justify-content: space-between; - flex-direction: row; - } - - h2 { - margin-bottom: 1rem; - } + &.two-columns { + max-width: 536px; + justify-content: space-between; + flex-direction: row; } - .avatar-form { - display: flex; - flex-direction: column; - width: 120px; - min-width: 120px; + h2 { + margin-bottom: 1rem; + } - img { - border-radius: 50%; - flex-shrink: 0; - height: 120px; - margin-right: $size-4; - width: 120px; - } + form { + width: 468px; - .image-change-field { - position: relative; - width: 120px; - height: 120px; - - .update-overlay { - opacity: 0; - cursor: pointer; - position: absolute; - width: 121px; - height: 121px; - border-radius: 50%; - font-size: $fs24; - color: $color-white; - line-height: $lh-500; // Original value was 120px; 120px/24px = 500% => $lh-500 - text-align: center; - background: $color-primary-dark; - z-index: 14; + .custom-input, + .custom-select { + flex-direction: column-reverse; + label { + position: relative; + text-transform: uppercase; + color: $df-primary; + font-size: 11px; + margin-bottom: 12px; + margin-left: -4px; } - - input[type="file"] { - width: 120px; - height: 120px; - position: absolute; - opacity: 0; - cursor: pointer; - top: 0; - z-index: 15; + input, + select { + background-color: $db-tertiary; + border-radius: 8px; + border-color: transparent; + color: $df-primary; + padding: 0 15px; + &:focus { + outline: 1px solid $da-primary; + } + ::placeholder { + color: $df-secondary; + } } - - &:hover { - .update-overlay { - opacity: 0.8; + .help-icon { + bottom: 12px; + top: auto; + svg { + fill: $df-secondary; + } + } + &.disabled { + input { + background-color: $db-primary; + border-color: $db-cuaternary; + color: $df-secondary; + } + } + .input-container { + background-color: $db-tertiary; + border-radius: 8px; + border-color: transparent; + margin-top: 22px; + .main-content { + label { + position: absolute; + top: -24px; + } + span { + color: $df-primary; + } + } + &:focus { + border: 1px solid $da-primary; + } + } + textarea { + border-radius: 8px; + padding: 12px 14px; + background-color: $db-tertiary; + color: $df-primary; + border: none; + &:focus { + outline: 1px solid $da-primary; } } } - } - .profile-form { - display: flex; - flex-direction: column; - max-width: 368px; - width: 100%; + .field-title { + color: $df-primary; + } + .field-title:not(:first-child) { + margin-top: 64px; + } - .newsletter-subs { - border-bottom: 1px solid $color-gray-20; - border-top: 1px solid $color-gray-20; - padding: 30px 0; - margin-bottom: 31px; - - .newsletter-title { - font-family: "worksans", sans-serif; - color: $color-gray-30; - font-size: $fs14; - } - - label { - font-family: "worksans", sans-serif; - color: $color-gray-60; - font-size: $fs12; - margin-right: -17px; - margin-bottom: 13px; - } - - .info { - font-family: "worksans", sans-serif; - color: $color-gray-30; - font-size: $fs12; - margin-bottom: 8px; - } - - .input-checkbox label { - align-items: flex-start; + .field-text { + color: $df-secondary; + } + button, + .btn-secondary { + width: 100%; + font-size: 11px; + text-transform: uppercase; + background-color: $db-tertiary; + color: $df-primary; + &:hover { + color: $da-primary; + background-color: $db-cuaternary; } } + hr { + display: none; + } } + .links { + margin-top: 12px; + } +} - .options-form, - .password-form { - h2 { - font-size: $fs14; - margin-bottom: 20px; +.profile-form { + display: flex; + flex-direction: column; + max-width: 368px; + width: 100%; + + .newsletter-subs { + border-bottom: 1px solid $df-secondary; + border-top: 1px solid $df-secondary; + padding: 30px 0; + margin-bottom: 31px; + + .newsletter-title { + font-family: "worksans", sans-serif; + color: $df-secondary; + font-size: $fs-14; + } + + label { + font-family: "worksans", sans-serif; + color: $db-primary; + font-size: $fs-12; + margin-right: -17px; + margin-bottom: 13px; + } + + .info { + font-family: "worksans", sans-serif; + color: $df-secondary; + font-size: $fs-12; + margin-bottom: 8px; + } + + .input-checkbox label { + align-items: flex-start; } } } + +.avatar-form { + display: flex; + flex-direction: column; + width: 120px; + min-width: 120px; + + img { + border-radius: 50%; + flex-shrink: 0; + height: 120px; + margin-right: $s-16; + width: 120px; + } + + .image-change-field { + position: relative; + width: 120px; + height: 120px; + + .update-overlay { + opacity: 0; + cursor: pointer; + position: absolute; + width: 121px; + height: 121px; + border-radius: 50%; + font-size: $fs-24; + color: $df-primary; + line-height: 5; + text-align: center; + background: $da-tertiary; + z-index: 14; + } + + input[type="file"] { + width: 120px; + height: 120px; + position: absolute; + opacity: 0; + cursor: pointer; + top: 0; + z-index: 15; + } + + &:hover { + .update-overlay { + opacity: 0.8; + } + } + } +} + +.options-form, +.password-form { + h2 { + font-size: $fs-14; + margin-bottom: 20px; + } +} diff --git a/frontend/src/app/main/ui/settings/access_tokens.cljs b/frontend/src/app/main/ui/settings/access_tokens.cljs index 5de70c98c3..6d5a0bafd3 100644 --- a/frontend/src/app/main/ui/settings/access_tokens.cljs +++ b/frontend/src/app/main/ui/settings/access_tokens.cljs @@ -423,4 +423,3 @@ (for [token tokens] [:& access-token-item {:token token :key (:id token)}])]])]]))) - diff --git a/frontend/src/app/main/ui/settings/access_tokens.scss b/frontend/src/app/main/ui/settings/access_tokens.scss index fd76557f71..2e9b8ef178 100644 --- a/frontend/src/app/main/ui/settings/access_tokens.scss +++ b/frontend/src/app/main/ui/settings/access_tokens.scss @@ -4,7 +4,170 @@ // // Copyright (c) KALEIDOS INC -@import "refactor/common-refactor.scss"; +@use "common/refactor/common-refactor.scss" as *; + +.dashboard-table { + display: flex; + flex-direction: column; + font-size: $fs-16; + margin-top: $s-20; + width: $s-800; + + .table-header { + color: $df-secondary; + display: grid; + font-size: $fs-12; + grid-template-columns: 43% 1fr $s-108 $s-12; + height: $s-40; + max-width: $s-1000; + padding: 0 $s-16; + text-transform: uppercase; + width: 100%; + } + + .table-rows { + color: $db-secondary; + display: flex; + flex-direction: column; + margin-top: $s-16; + max-width: $s-1000; + padding-top: 0; + width: 100%; + } + + .table-row { + align-items: center; + background-color: $db-tertiary; + border-radius: $br-8; + color: $df-primary; + display: grid; + font-size: $fs-14; + grid-template-columns: 1fr 43% $s-12; + height: fit-content; + min-height: $s-40; + padding: 0 $s-16; + width: 100%; + + &:not(:first-child) { + margin-top: $s-8; + } + } + + .table-field { + display: flex; + align-items: center; + + .icon { + padding-left: $s-12; + cursor: pointer; + } + + &.name { + -webkit-box-orient: vertical; + -webkit-line-clamp: 2; + color: $df-primary; + display: -webkit-box; + max-width: $s-480; + overflow: hidden; + text-overflow: ellipsis; + } + + &.expiration-date { + color: $df-secondary; + font-size: $fs-14; + + .content { + padding: $s-2 $s-6; + &.expired { + background-color: var(--warning-color); + border-radius: $br-4; + color: $db-secondary; + } + } + } + &.access-token-created { + word-break: break-all; + } + + &.actions { + position: relative; + } + } + + svg { + width: $s-12; + height: $s-12; + fill: $df-primary; + } +} + +.dashboard-access-tokens { + display: flex; + flex-direction: column; + margin-left: $s-120; + margin-top: $s-80; + width: $s-800; +} + +.access-tokens-hero-container { + background-color: transparent; + display: flex; + flex-direction: column; + max-width: $s-1000; + width: 100%; +} + +.access-tokens-hero { + display: flex; + flex-direction: column; + font-size: $fs-14; + gap: $s-32; + justify-content: space-between; + width: $s-468; + + .desc { + background-color: transparent; + color: $df-secondary; + width: 100%; + + h2 { + color: $df-primary; + font-size: $fs-24; + font-weight: regular; + margin-bottom: $s-32; + } + p { + color: $df-secondary; + margin-bottom: 0; + font-size: $fs-14; + } + } + .btn-primary { + flex-shrink: 0; + } +} + +.access-tokens-empty { + align-items: center; + border-radius: $br-8; + border: $s-1 solid $db-cuaternary; + color: $df-secondary; + display: flex; + flex-direction: column; + font-size: $fs-14; + justify-content: center; + margin-top: $s-32; + max-width: $s-1000; + min-height: $s-136; + padding: $s-32; + text-align: center; + width: $s-468; +} + +.btn-primary { + @extend .button-primary; + height: $s-32; +} .modal-overlay { @extend .modal-overlay-base; @@ -80,849 +243,3 @@ } } } - -////// - -@import "common/dependencies/colors"; - -$br3: 3px; -$br4: 4px; -$br8: 8px; -$br6: 6px; -$fs12: 0.75rem; -$fs14: 0.875rem; -$fs16: 1rem; -$fs18: 1.125rem; -$fs22: 1.375rem; -$fs24: 1.5rem; -$fs36: 2.25rem; -$fw400: 400; -$fw500: 500; -$fw600: 600; -$fw700: 700; -$lh-088: 0.88; -$lh-115: 1.15; // original $title-lh-sm -$lh-500: 5; // original $title-lh-sm -$size-1: 0.25rem; -$size-2: 0.5rem; -$size-4: 1rem; -$size-5: 1.5rem; -$size-6: 2rem; - -.form-container, -.generic-form { - display: flex; - justify-content: center; - flex-direction: column; - - .forms-container { - display: flex; - margin-top: 40px; - width: 536px; - justify-content: center; - } - - form { - display: flex; - flex-direction: column; - // flex-basis: 368px; - } - - .fields-row { - margin-bottom: 20px; - flex-direction: column; - - .options { - display: flex; - justify-content: flex-end; - font-size: $fs14; - margin-top: 13px; - } - } - - .field { - margin-bottom: 20px; - } - - h1 { - font-size: $fs36; - color: #2c233e; - margin-bottom: 20px; - } - - .subtitle { - font-size: $fs24; - color: #2c233e; - margin-bottom: 20px; - } - - .notification-icon { - justify-content: center; - display: flex; - margin-bottom: 3rem; - - svg { - fill: $color-gray-60; - height: 40%; - width: 40%; - } - } - - .notification-text { - font-size: $fs18; - color: $color-gray-60; - margin-bottom: 20px; - } - - .notification-text-email { - background: $color-gray-10; - border-radius: $br3; - color: $color-gray-60; - font-size: $fs18; - font-weight: $fw500; - margin: 1.5rem 0 2.5rem 0; - padding: 1rem; - text-align: center; - } - - h2 { - font-size: $fs24; - color: $color-gray-60; - // height: 40px; - display: flex; - align-items: center; - } - - a { - &:hover { - text-decoration: underline; - } - } - - p { - color: $color-gray-60; - } - - hr { - border-color: $color-gray-20; - } -} - -.dashboard-header { - display: flex; - align-items: center; - justify-content: space-between; - background-color: $color-white; - height: 63px; - padding: $size-1 $size-4 $size-1 $size-2; - position: relative; - z-index: 10; - user-select: none; - &.team { - display: grid; - grid-template-columns: 20% 1fr 20%; - } - - .element-name { - margin-right: $size-2; - } - - .btn-secondary { - flex-shrink: 0; - z-index: 10; - height: 32px; - svg { - height: 16px; - width: 16px; - } - } - - svg { - fill: $color-black; - height: 14px; - margin-right: $size-1; - width: 14px; - } - - nav { - display: flex; - align-items: flex-end; - justify-content: center; - z-index: 1; - - ul { - display: flex; - font-size: $fs14; - justify-content: center; - margin: 0; - } - - li { - a { - display: flex; - align-items: center; - flex-basis: 140px; - border-bottom: 3px solid transparent; - color: $color-gray-30; - height: 40px; - padding: $size-1 $size-5; - font-weight: $fw400; - &:hover { - color: $color-black; - text-decoration: none; - } - } - - &.active { - a { - color: $color-black; - border-color: $color-primary; - } - } - } - } - - .dashboard-title { - display: flex; - align-items: center; - margin-left: 13px; - - h1 { - color: $color-black; - display: flex; - flex-shrink: 0; - font-size: $fs22; - font-weight: $fw600; - z-index: 10; - user-select: all; - } - - .context-menu.is-open { - margin-top: 10px; - } - } - - .icon { - display: flex; - align-items: center; - cursor: pointer; - margin-left: $size-2; - z-index: 10; - - svg { - fill: $color-gray-40; - width: 15px; - height: 15px; - - &:hover { - fill: $color-primary-dark; - } - } - } - - .dashboard-buttons { - display: flex; - justify-content: flex-end; - align-items: center; - } - - .dashboard-header-actions { - display: flex; - } - - .pin-icon { - margin: 0 $size-2 0 $size-5; - background-color: transparent; - border: none; - svg { - fill: $color-gray-20; - } - - &.active { - svg { - fill: $color-gray-50; - } - } - } -} - -.dashboard-settings { - display: flex; - width: 100%; - justify-content: center; - align-items: center; - - .form-container { - margin-top: 50px; - display: flex; - max-width: 368px; - margin-bottom: 2rem; - width: 100%; - - &.two-columns { - max-width: 536px; - justify-content: space-between; - flex-direction: row; - } - - h2 { - margin-bottom: 1rem; - } - } - - .avatar-form { - display: flex; - flex-direction: column; - width: 120px; - min-width: 120px; - - img { - border-radius: 50%; - flex-shrink: 0; - height: 120px; - margin-right: $size-4; - width: 120px; - } - - .image-change-field { - position: relative; - width: 120px; - height: 120px; - - .update-overlay { - opacity: 0; - cursor: pointer; - position: absolute; - width: 121px; - height: 121px; - border-radius: 50%; - font-size: $fs24; - color: $color-white; - line-height: $lh-500; // Original value was 120px; 120px/24px = 500% => $lh-500 - text-align: center; - background: $color-primary-dark; - z-index: 14; - } - - input[type="file"] { - width: 120px; - height: 120px; - position: absolute; - opacity: 0; - cursor: pointer; - top: 0; - z-index: 15; - } - - &:hover { - .update-overlay { - opacity: 0.8; - } - } - } - } - - .profile-form { - display: flex; - flex-direction: column; - max-width: 368px; - width: 100%; - - .newsletter-subs { - border-bottom: 1px solid $color-gray-20; - border-top: 1px solid $color-gray-20; - padding: 30px 0; - margin-bottom: 31px; - - .newsletter-title { - font-family: "worksans", sans-serif; - color: $color-gray-30; - font-size: $fs14; - } - - label { - font-family: "worksans", sans-serif; - color: $color-gray-60; - font-size: $fs12; - margin-right: -17px; - margin-bottom: 13px; - } - - .info { - font-family: "worksans", sans-serif; - color: $color-gray-30; - font-size: $fs12; - margin-bottom: 8px; - } - - .input-checkbox label { - align-items: flex-start; - } - } - } - - .options-form, - .password-form { - h2 { - font-size: $fs14; - margin-bottom: 20px; - } - } -} - -.access-tokens-modal { - .action-buttons { - gap: 10px; - - .cancel-button { - border: 1px solid $color-gray-30; - background: $color-canvas; - border-radius: $br3; - padding: 0.5rem 1rem; - cursor: pointer; - margin-right: 8px; - - &:hover { - background: $color-gray-20; - } - } - } - .access-token-created { - position: relative; - word-break: break-all; - - .custom-input input { - background-color: $color-success-lighter; - border: 0; - padding: 0 0 0 15px; - } - } - - .help-icon { - border: none; - height: 40px; - width: 40px; - position: absolute; - top: 0; - right: 0; - cursor: pointer; - background-color: $color-success-lighter; - - svg { - fill: $color-gray-30; - } - - &:hover { - svg { - fill: $color-gray-60; - } - } - } - - .token-created-info { - font-size: $fs12; - color: $color-gray-40; - } -} - -.dashboard-settings { - a { - color: $df-secondary; - } - .form-container { - width: 800px; - margin: 80px auto auto 120px; - form { - width: 468px; - .fields-row { - .custom-input, - .custom-select { - flex-direction: column-reverse; - label { - position: relative; - text-transform: uppercase; - color: $df-primary; - font-size: 11px; - margin-bottom: 12px; - margin-left: -4px; - } - input, - select { - background-color: $db-tertiary; - border-radius: 8px; - border-color: transparent; - color: $df-primary; - padding: 0 15px; - &:focus { - outline: 1px solid $da-primary; - } - ::placeholder { - color: $df-secondary; - } - } - .help-icon { - bottom: 12px; - top: auto; - svg { - fill: $df-secondary; - } - } - &.disabled { - input { - background-color: $db-primary; - border-color: $db-cuaternary; - color: $df-secondary; - } - } - .input-container { - background-color: $db-tertiary; - border-radius: 8px; - border-color: transparent; - margin-top: 22px; - .main-content { - label { - position: absolute; - top: -24px; - } - span { - color: $df-primary; - } - } - &:focus { - border: 1px solid $da-primary; - } - } - textarea { - border-radius: 8px; - padding: 12px 14px; - background-color: $db-tertiary; - color: $df-primary; - border: none; - &:focus { - outline: 1px solid $da-primary; - } - } - } - } - .field-title { - color: $df-primary; - } - .field-title:not(:first-child) { - margin-top: 64px; - } - - .field-text { - color: $df-secondary; - } - button, - .btn-secondary { - width: 100%; - font-size: 11px; - text-transform: uppercase; - background-color: $db-tertiary; - color: $df-primary; - &:hover { - color: $da-primary; - background-color: $db-cuaternary; - } - } - hr { - display: none; - } - } - .links { - margin-top: 12px; - } - } -} - -.dashboard-table { - display: flex; - flex-direction: column; - align-items: center; - margin-top: 20px; - font-size: $fs16; - - &.team-members { - margin-bottom: 52px; - } - - &.invitations { - .table-row { - display: grid; - grid-template-columns: 43% 1fr 109px 12px; - } - } - - .table-header { - display: grid; - grid-template-columns: 43% 1fr 109px 12px; - max-width: 1040px; - background-color: $color-white; - color: $color-gray-30; - width: 100%; - height: 40px; - padding: 0px 16px; - } - - .table-rows { - display: flex; - flex-direction: column; - max-width: 1040px; - width: 100%; - margin-top: 16px; - color: $color-black; - } - - .table-row { - display: flex; - width: 100%; - height: 45px; - align-items: center; - padding: 0px 16px; - } - - .table-field { - display: flex; - align-items: center; - - .icon { - padding-left: 10px; - cursor: pointer; - } - } - - svg { - width: 10px; - height: 10px; - fill: $df-primary; - } -} - -.dashboard-table { - .table-header { - background-color: transparent; - color: $df-secondary; - font-size: 12px; - text-transform: uppercase; - } - .table-rows { - .table-row { - background-color: $db-tertiary; - border-radius: 8px; - color: $df-primary; - .rol-selector { - background-color: $db-cuaternary; - border-color: transparent; - border-radius: 8px; - } - } - } - .member-info { - .member-name .you, - .member-email { - color: $df-secondary; - } - } - .status-badge { - border-radius: 8px; - color: $db-primary; - text-transform: uppercase; - } - .empty-invitations { - border: 1px solid $db-cuaternary; - border-radius: 8px; - color: $df-secondary; - } -} - -.dashboard-access-tokens { - width: 800px; - margin-left: 120px; - margin-top: 80px; - .access-tokens-hero-container { - background-color: transparent; - .access-tokens-hero { - width: 468px; - flex-direction: column; - gap: 32px; - background-color: transparent; - margin: 0; - padding: 0; - .desc { - background-color: transparent; - width: 100%; - h2 { - color: $df-primary; - font-size: 24px; - font-weight: regular; - margin-bottom: 32px; - } - p { - color: $df-secondary; - margin-bottom: 0; - font-size: 14px; - } - } - button { - width: 100%; - font-size: 11px; - text-transform: uppercase; - background-color: $db-tertiary; - color: $df-primary; - &:hover { - color: $da-primary; - background-color: $db-cuaternary; - } - } - } - } - .dashboard-table { - width: 800px; - .table-rows { - padding-top: 0; - .table-row { - font-size: 14px; - min-height: 40px; - height: fit-content; - .name { - color: $df-primary; - max-width: 480px; - overflow: hidden; - text-overflow: ellipsis; - display: -webkit-box; - -webkit-line-clamp: 2; - -webkit-box-orient: vertical; - } - .expiration-date { - color: $df-secondary; - } - } - } - } - .access-tokens-empty { - width: 468px; - border: 1px solid $db-cuaternary; - border-radius: 8px; - margin-top: 32px; - font-size: 14px; - background-color: transparent; - color: $df-secondary; - } -} - -.dashboard-access-tokens { - display: flex; - flex-direction: column; - align-items: center; - - .access-tokens-hero-container { - max-width: 1000px; - width: 100%; - display: flex; - flex-direction: column; - } - - .access-tokens-hero { - font-size: $fs14; - padding: $size-6; - background-color: $color-white; - margin-top: $size-6; - display: flex; - justify-content: space-between; - - .desc { - width: 80%; - color: $color-gray-40; - h2 { - margin-bottom: $size-4; - color: $color-black; - } - p { - font-size: $fs16; - } - } - - .btn-primary { - flex-shrink: 0; - } - } - - .access-tokens-empty { - text-align: center; - max-width: 1000px; - width: 100%; - padding: $size-6; - display: flex; - flex-direction: column; - justify-content: center; - align-items: center; - border: 1px dashed $color-gray-20; - color: $color-gray-40; - margin-top: 12px; - min-height: 136px; - } - - .table-row { - background-color: $color-white; - display: grid; - grid-template-columns: 1fr 43% 12px; - height: 63px; - &:not(:first-child) { - margin-top: 8px; - } - } - - .table-field { - &.name { - color: $color-gray-60; - } - - &.expiration-date { - color: $color-gray-40; - font-size: $fs14; - .content { - padding: 2px 5px; - &.expired { - background-color: $color-warning-lighter; - border-radius: $br4; - color: $color-gray-40; - } - } - } - - &.access-token-created { - word-break: break-all; - } - - &.actions { - position: relative; - } - } -} - -.btn-primary { - background-color: $da-tertiary; - border-radius: 8px; - color: $db-primary; - height: 32px; - text-transform: uppercase; - - appearance: none; - align-items: center; - border: none; - cursor: pointer; - display: flex; - font-family: "worksans", sans-serif; - font-size: $fs12; - justify-content: center; - min-width: 25px; - padding: 0 1rem; - transition: all 0.4s; - text-decoration: none; - - &:hover { - background-color: darken($da-tertiary, 10%); - color: $db-primary; - } -} diff --git a/frontend/src/app/main/ui/settings/feedback.cljs b/frontend/src/app/main/ui/settings/feedback.cljs index 711537fe30..d59185f13c 100644 --- a/frontend/src/app/main/ui/settings/feedback.cljs +++ b/frontend/src/app/main/ui/settings/feedback.cljs @@ -63,7 +63,7 @@ (rx/subs on-succes on-error)))))] (if new-css-system - [:& fm/form {:class "feedback-form" + [:& fm/form {:class (stl/css :feedback-form) :on-submit on-submit :form form} @@ -159,4 +159,3 @@ [:div.dashboard-settings [:div.form-container [:& feedback-form]]]))) - diff --git a/frontend/src/app/main/ui/settings/feedback.scss b/frontend/src/app/main/ui/settings/feedback.scss index bc73d1e2fc..dec2597db0 100644 --- a/frontend/src/app/main/ui/settings/feedback.scss +++ b/frontend/src/app/main/ui/settings/feedback.scss @@ -1,690 +1,25 @@ -@import "common/dependencies/colors"; - -$br2: 2px; -$br3: 3px; -$br4: 4px; -$br8: 8px; -$br6: 6px; -$fs12: 0.75rem; -$fs14: 0.875rem; -$fs16: 1rem; -$fs18: 1.125rem; -$fs22: 1.375rem; -$fs24: 1.5rem; -$fs36: 2.25rem; -$fw400: 400; -$fw500: 500; -$fw600: 600; -$fw700: 700; -$lh-088: 0.88; -$lh-115: 1.15; // original $title-lh-sm -$lh-500: 5; // original $title-lh-sm -$size-1: 0.25rem; -$size-2: 0.5rem; -$size-4: 1rem; -$size-5: 1.5rem; -$size-6: 2rem; - -.form-container, -.generic-form { - display: flex; - justify-content: center; - flex-direction: column; - - .forms-container { - display: flex; - margin-top: 40px; - width: 536px; - justify-content: center; - } - - form { - display: flex; - flex-direction: column; - // flex-basis: 368px; - } - - .fields-row { - margin-bottom: 20px; - flex-direction: column; - - .options { - display: flex; - justify-content: flex-end; - font-size: $fs14; - margin-top: 13px; - } - } - - .field { - margin-bottom: 20px; - } - - h1 { - font-size: $fs36; - color: #2c233e; - margin-bottom: 20px; - } - - .subtitle { - font-size: $fs24; - color: #2c233e; - margin-bottom: 20px; - } - - .notification-icon { - justify-content: center; - display: flex; - margin-bottom: 3rem; - - svg { - fill: $color-gray-60; - height: 40%; - width: 40%; - } - } - - .notification-text { - font-size: $fs18; - color: $color-gray-60; - margin-bottom: 20px; - } - - .notification-text-email { - background: $color-gray-10; - border-radius: $br3; - color: $color-gray-60; - font-size: $fs18; - font-weight: $fw500; - margin: 1.5rem 0 2.5rem 0; - padding: 1rem; - text-align: center; - } - - h2 { - font-size: $fs24; - color: $color-gray-60; - // height: 40px; - display: flex; - align-items: center; - } - - a { - &:hover { - text-decoration: underline; - } - } - - p { - color: $color-gray-60; - } - - hr { - border-color: $color-gray-20; - } -} - -.dashboard-header { - display: flex; - align-items: center; - justify-content: space-between; - background-color: $color-white; - height: 63px; - padding: $size-1 $size-4 $size-1 $size-2; - position: relative; - z-index: 10; - user-select: none; - &.team { - display: grid; - grid-template-columns: 20% 1fr 20%; - } - - .element-name { - margin-right: $size-2; - } - - .btn-secondary { - flex-shrink: 0; - z-index: 10; - height: 32px; - svg { - height: 16px; - width: 16px; - } - } - - svg { - fill: $color-black; - height: 14px; - margin-right: $size-1; - width: 14px; - } - - nav { - display: flex; - align-items: flex-end; - justify-content: center; - z-index: 1; - - ul { - display: flex; - font-size: $fs14; - justify-content: center; - margin: 0; - } - - li { - a { - display: flex; - align-items: center; - flex-basis: 140px; - border-bottom: 3px solid transparent; - color: $color-gray-30; - height: 40px; - padding: $size-1 $size-5; - font-weight: $fw400; - &:hover { - color: $color-black; - text-decoration: none; - } - } - - &.active { - a { - color: $color-black; - border-color: $color-primary; - } - } - } - } - - .dashboard-title { - display: flex; - align-items: center; - margin-left: 13px; - - h1 { - color: $color-black; - display: flex; - flex-shrink: 0; - font-size: $fs22; - font-weight: $fw600; - z-index: 10; - user-select: all; - } - - .context-menu.is-open { - margin-top: 10px; - } - } - - .icon { - display: flex; - align-items: center; - cursor: pointer; - margin-left: $size-2; - z-index: 10; - - svg { - fill: $color-gray-40; - width: 15px; - height: 15px; - - &:hover { - fill: $color-primary-dark; - } - } - } - - .dashboard-buttons { - display: flex; - justify-content: flex-end; - align-items: center; - } - - .dashboard-header-actions { - display: flex; - } - - .pin-icon { - margin: 0 $size-2 0 $size-5; - background-color: transparent; - border: none; - svg { - fill: $color-gray-20; - } - - &.active { - svg { - fill: $color-gray-50; - } - } - } -} - -.dashboard-settings { - display: flex; - width: 100%; - justify-content: center; - align-items: center; - - .form-container { - margin-top: 50px; - display: flex; - max-width: 368px; - margin-bottom: 2rem; - width: 100%; - - &.two-columns { - max-width: 536px; - justify-content: space-between; - flex-direction: row; - } - - h2 { - margin-bottom: 1rem; - } - } - - .avatar-form { - display: flex; - flex-direction: column; - width: 120px; - min-width: 120px; - - img { - border-radius: 50%; - flex-shrink: 0; - height: 120px; - margin-right: $size-4; - width: 120px; - } - - .image-change-field { - position: relative; - width: 120px; - height: 120px; - - .update-overlay { - opacity: 0; - cursor: pointer; - position: absolute; - width: 121px; - height: 121px; - border-radius: 50%; - font-size: $fs24; - color: $color-white; - line-height: $lh-500; // Original value was 120px; 120px/24px = 500% => $lh-500 - text-align: center; - background: $color-primary-dark; - z-index: 14; - } - - input[type="file"] { - width: 120px; - height: 120px; - position: absolute; - opacity: 0; - cursor: pointer; - top: 0; - z-index: 15; - } - - &:hover { - .update-overlay { - opacity: 0.8; - } - } - } - } - - .profile-form { - display: flex; - flex-direction: column; - max-width: 368px; - width: 100%; - - .newsletter-subs { - border-bottom: 1px solid $color-gray-20; - border-top: 1px solid $color-gray-20; - padding: 30px 0; - margin-bottom: 31px; - - .newsletter-title { - font-family: "worksans", sans-serif; - color: $color-gray-30; - font-size: $fs14; - } - - label { - font-family: "worksans", sans-serif; - color: $color-gray-60; - font-size: $fs12; - margin-right: -17px; - margin-bottom: 13px; - } - - .info { - font-family: "worksans", sans-serif; - color: $color-gray-30; - font-size: $fs12; - margin-bottom: 8px; - } - - .input-checkbox label { - align-items: flex-start; - } - } - } - - .options-form, - .password-form { - h2 { - font-size: $fs14; - margin-bottom: 20px; - } - } -} - -.dashboard-access-tokens { - display: flex; - flex-direction: column; - align-items: center; - - .access-tokens-hero-container { - max-width: 1000px; - width: 100%; - display: flex; - flex-direction: column; - } - - .access-tokens-hero { - font-size: $fs14; - padding: $size-6; - background-color: $color-white; - margin-top: $size-6; - display: flex; - justify-content: space-between; - - .desc { - width: 80%; - color: $color-gray-40; - h2 { - margin-bottom: $size-4; - color: $color-black; - } - p { - font-size: $fs16; - } - } - - .btn-primary { - flex-shrink: 0; - } - } - - .access-tokens-empty { - text-align: center; - max-width: 1000px; - width: 100%; - padding: $size-6; - display: flex; - flex-direction: column; - justify-content: center; - align-items: center; - border: 1px dashed $color-gray-20; - color: $color-gray-40; - margin-top: 12px; - min-height: 136px; - } - - .table-row { - background-color: $color-white; - display: grid; - grid-template-columns: 1fr 43% 12px; - height: 63px; - &:not(:first-child) { - margin-top: 8px; - } - } - - .table-field { - &.name { - color: $color-gray-60; - } - - &.expiration-date { - color: $color-gray-40; - font-size: $fs14; - .content { - padding: 2px 5px; - &.expired { - background-color: $color-warning-lighter; - border-radius: $br4; - color: $color-gray-40; - } - } - } - - &.access-token-created { - word-break: break-all; - } - - &.actions { - position: relative; - } - } -} - -.access-tokens-modal { - .action-buttons { - gap: 10px; - - .cancel-button { - border: 1px solid $color-gray-30; - background: $color-canvas; - border-radius: $br3; - padding: 0.5rem 1rem; - cursor: pointer; - margin-right: 8px; - - &:hover { - background: $color-gray-20; - } - } - } - .access-token-created { - position: relative; - word-break: break-all; - - .custom-input input { - background-color: $color-success-lighter; - border: 0; - padding: 0 0 0 15px; - } - } - - .help-icon { - border: none; - height: 40px; - width: 40px; - position: absolute; - top: 0; - right: 0; - cursor: pointer; - background-color: $color-success-lighter; - - svg { - fill: $color-gray-30; - } - - &:hover { - svg { - fill: $color-gray-60; - } - } - } - - .token-created-info { - font-size: $fs12; - color: $color-gray-40; - } -} - -.dashboard-settings { - a { - color: $df-secondary; - } - .form-container { - width: 800px; - margin: 80px auto auto 120px; - form { - width: 468px; - .fields-row { - .custom-input, - .custom-select { - flex-direction: column-reverse; - label { - position: relative; - text-transform: uppercase; - color: $df-primary; - font-size: 11px; - margin-bottom: 12px; - margin-left: -4px; - } - input, - select { - background-color: $db-tertiary; - border-radius: 8px; - border-color: transparent; - color: $df-primary; - padding: 0 15px; - &:focus { - outline: 1px solid $da-primary; - } - ::placeholder { - color: $df-secondary; - } - } - .help-icon { - bottom: 12px; - top: auto; - svg { - fill: $df-secondary; - } - } - &.disabled { - input { - background-color: $db-primary; - border-color: $db-cuaternary; - color: $df-secondary; - } - } - .input-container { - background-color: $db-tertiary; - border-radius: 8px; - border-color: transparent; - margin-top: 22px; - .main-content { - label { - position: absolute; - top: -24px; - } - span { - color: $df-primary; - } - } - &:focus { - border: 1px solid $da-primary; - } - } - textarea { - border-radius: 8px; - padding: 12px 14px; - background-color: $db-tertiary; - color: $df-primary; - border: none; - &:focus { - outline: 1px solid $da-primary; - } - } - } - } - .field-title { - color: $df-primary; - } - .field-title:not(:first-child) { - margin-top: 64px; - } - - .field-text { - color: $df-secondary; - } - button, - .btn-secondary { - width: 100%; - font-size: 11px; - text-transform: uppercase; - background-color: $db-tertiary; - color: $df-primary; - &:hover { - color: $da-primary; - background-color: $db-cuaternary; - } - } - hr { - display: none; - } - } - .links { - margin-top: 12px; - } - } -} - -.btn-secondary { - background-color: $db-tertiary; - text-transform: uppercase; - border: none; - color: $df-primary; - border-radius: 8px; - - font-size: 0.75rem; - padding: 0 1rem; - cursor: pointer; - display: flex; - justify-content: center; - align-items: center; - height: 40px; - - &:hover { - background-color: $db-cuaternary; - color: $da-primary; - svg { - fill: $da-primary; - } - } -} - -.description { - :global(.custom-input label) { - position: initial; - margin-bottom: 8px; - } - - :global(.custom-input textarea) { - background-color: $color-white; +// 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" as *; +@use "./profile"; + +.feedback-form { + textarea { + border-radius: $br-8; + padding: $br-12; background-color: $db-tertiary; - border-radius: 8px; - border: none; color: $df-primary; - font-size: $fs14; - margin: 0; - padding: 15px 15px 0 15px; - width: 100%; + border: none; + ::placeholder { + color: $db-disabled; + } &:focus { - outline: 1px solid $da-primary; + outline: $s-1 solid $da-primary; } } } diff --git a/frontend/src/app/main/ui/settings/options.cljs b/frontend/src/app/main/ui/settings/options.cljs index 78a0c5130a..2ec2476590 100644 --- a/frontend/src/app/main/ui/settings/options.cljs +++ b/frontend/src/app/main/ui/settings/options.cljs @@ -50,7 +50,7 @@ :on-submit on-submit :form form} - [:h2 (tr "labels.language")] + [:h3 (tr "labels.language")] [:div {:class (stl/css :fields-row)} [:& fm/select {:options (into [{:label "Auto (browser)" :value ""}] @@ -60,7 +60,7 @@ :name :lang :data-test "setting-lang"}]] - [:h2 (tr "dashboard.theme-change")] + [:h3 (tr "dashboard.theme-change")] [:div {:class (stl/css :fields-row)} [:& fm/select {:label (tr "dashboard.select-ui-theme") :name :theme @@ -71,7 +71,8 @@ [:> fm/submit-button* {:label (tr "dashboard.update-settings") - :data-test "submit-lang-change"}]] + :data-test "submit-lang-change" + :class (stl/css :btn-primary)}]] ;; OLD [:& fm/form {:class "options-form" @@ -102,9 +103,8 @@ (if new-css-system [:div {:class (stl/css :dashboard-settings)} - [:div - {:class (stl/css :form-container) - :data-test "settings-form"} + [:div {:class (stl/css :form-container) :data-test "settings-form"} + [:h2 (tr "labels.settings")] [:& options-form {}]]] ;; OLD diff --git a/frontend/src/app/main/ui/settings/options.scss b/frontend/src/app/main/ui/settings/options.scss index 0f94e82b4f..474e96838f 100644 --- a/frontend/src/app/main/ui/settings/options.scss +++ b/frontend/src/app/main/ui/settings/options.scss @@ -1,642 +1,7 @@ -@import "common/dependencies/colors"; +// 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 -$br3: 3px; -$br4: 4px; -$br8: 8px; -$br6: 6px; -$fs12: 0.75rem; -$fs14: 0.875rem; -$fs16: 1rem; -$fs18: 1.125rem; -$fs22: 1.375rem; -$fs24: 1.5rem; -$fs36: 2.25rem; -$fw400: 400; -$fw500: 500; -$fw600: 600; -$fw700: 700; -$lh-088: 0.88; -$lh-115: 1.15; // original $title-lh-sm -$lh-500: 5; // original $title-lh-sm -$size-1: 0.25rem; -$size-2: 0.5rem; -$size-4: 1rem; -$size-5: 1.5rem; -$size-6: 2rem; - -.form-container, -.generic-form { - display: flex; - justify-content: center; - flex-direction: column; - - .forms-container { - display: flex; - margin-top: 40px; - width: 536px; - justify-content: center; - } - - form { - display: flex; - flex-direction: column; - // flex-basis: 368px; - } - - .fields-row { - margin-bottom: 20px; - flex-direction: column; - - .options { - display: flex; - justify-content: flex-end; - font-size: $fs14; - margin-top: 13px; - } - } - - .field { - margin-bottom: 20px; - } - - h1 { - font-size: $fs36; - color: #2c233e; - margin-bottom: 20px; - } - - .subtitle { - font-size: $fs24; - color: #2c233e; - margin-bottom: 20px; - } - - .notification-icon { - justify-content: center; - display: flex; - margin-bottom: 3rem; - - svg { - fill: $color-gray-60; - height: 40%; - width: 40%; - } - } - - .notification-text { - font-size: $fs18; - color: $color-gray-60; - margin-bottom: 20px; - } - - .notification-text-email { - background: $color-gray-10; - border-radius: $br3; - color: $color-gray-60; - font-size: $fs18; - font-weight: $fw500; - margin: 1.5rem 0 2.5rem 0; - padding: 1rem; - text-align: center; - } - - h2 { - font-size: $fs24; - color: $df-primary; - // height: 40px; - display: flex; - align-items: center; - } - - a { - &:hover { - text-decoration: underline; - } - } - - p { - color: $color-gray-60; - } - - hr { - border-color: $color-gray-20; - } -} - -.dashboard-header { - display: flex; - align-items: center; - justify-content: space-between; - background-color: $color-white; - height: 63px; - padding: $size-1 $size-4 $size-1 $size-2; - position: relative; - z-index: 10; - user-select: none; - &.team { - display: grid; - grid-template-columns: 20% 1fr 20%; - } - - .element-name { - margin-right: $size-2; - } - - .btn-secondary { - flex-shrink: 0; - z-index: 10; - height: 32px; - svg { - height: 16px; - width: 16px; - } - } - - svg { - fill: $color-black; - height: 14px; - margin-right: $size-1; - width: 14px; - } - - nav { - display: flex; - align-items: flex-end; - justify-content: center; - z-index: 1; - - ul { - display: flex; - font-size: $fs14; - justify-content: center; - margin: 0; - } - - li { - a { - display: flex; - align-items: center; - flex-basis: 140px; - border-bottom: 3px solid transparent; - color: $color-gray-30; - height: 40px; - padding: $size-1 $size-5; - font-weight: $fw400; - &:hover { - color: $color-black; - text-decoration: none; - } - } - - &.active { - a { - color: $color-black; - border-color: $color-primary; - } - } - } - } - - .dashboard-title { - display: flex; - align-items: center; - margin-left: 13px; - - h1 { - color: $color-black; - display: flex; - flex-shrink: 0; - font-size: $fs22; - font-weight: $fw600; - z-index: 10; - user-select: all; - } - - .context-menu.is-open { - margin-top: 10px; - } - } - - .icon { - display: flex; - align-items: center; - cursor: pointer; - margin-left: $size-2; - z-index: 10; - - svg { - fill: $color-gray-40; - width: 15px; - height: 15px; - - &:hover { - fill: $color-primary-dark; - } - } - } - - .dashboard-buttons { - display: flex; - justify-content: flex-end; - align-items: center; - } - - .dashboard-header-actions { - display: flex; - } - - .pin-icon { - margin: 0 $size-2 0 $size-5; - background-color: transparent; - border: none; - svg { - fill: $color-gray-20; - } - - &.active { - svg { - fill: $color-gray-50; - } - } - } -} - -.dashboard-settings { - display: flex; - width: 100%; - justify-content: center; - align-items: center; - - .form-container { - margin-top: 50px; - display: flex; - max-width: 368px; - margin-bottom: 2rem; - width: 100%; - - &.two-columns { - max-width: 536px; - justify-content: space-between; - flex-direction: row; - } - - h2 { - margin-bottom: 1rem; - } - } - - .avatar-form { - display: flex; - flex-direction: column; - width: 120px; - min-width: 120px; - - img { - border-radius: 50%; - flex-shrink: 0; - height: 120px; - margin-right: $size-4; - width: 120px; - } - - .image-change-field { - position: relative; - width: 120px; - height: 120px; - - .update-overlay { - opacity: 0; - cursor: pointer; - position: absolute; - width: 121px; - height: 121px; - border-radius: 50%; - font-size: $fs24; - color: $color-white; - line-height: $lh-500; // Original value was 120px; 120px/24px = 500% => $lh-500 - text-align: center; - background: $color-primary-dark; - z-index: 14; - } - - input[type="file"] { - width: 120px; - height: 120px; - position: absolute; - opacity: 0; - cursor: pointer; - top: 0; - z-index: 15; - } - - &:hover { - .update-overlay { - opacity: 0.8; - } - } - } - } - - .profile-form { - display: flex; - flex-direction: column; - max-width: 368px; - width: 100%; - - .newsletter-subs { - border-bottom: 1px solid $color-gray-20; - border-top: 1px solid $color-gray-20; - padding: 30px 0; - margin-bottom: 31px; - - .newsletter-title { - font-family: "worksans", sans-serif; - color: $color-gray-30; - font-size: $fs14; - } - - label { - font-family: "worksans", sans-serif; - color: $color-gray-60; - font-size: $fs12; - margin-right: -17px; - margin-bottom: 13px; - } - - .info { - font-family: "worksans", sans-serif; - color: $color-gray-30; - font-size: $fs12; - margin-bottom: 8px; - } - - .input-checkbox label { - align-items: flex-start; - } - } - } - - .options-form, - .password-form { - h2 { - font-size: $fs14; - margin-bottom: 20px; - } - } -} - -.dashboard-access-tokens { - display: flex; - flex-direction: column; - align-items: center; - - .access-tokens-hero-container { - max-width: 1000px; - width: 100%; - display: flex; - flex-direction: column; - } - - .access-tokens-hero { - font-size: $fs14; - padding: $size-6; - background-color: $color-white; - margin-top: $size-6; - display: flex; - justify-content: space-between; - - .desc { - width: 80%; - color: $color-gray-40; - h2 { - margin-bottom: $size-4; - color: $color-black; - } - p { - font-size: $fs16; - } - } - - .btn-primary { - flex-shrink: 0; - } - } - - .access-tokens-empty { - text-align: center; - max-width: 1000px; - width: 100%; - padding: $size-6; - display: flex; - flex-direction: column; - justify-content: center; - align-items: center; - border: 1px dashed $color-gray-20; - color: $color-gray-40; - margin-top: 12px; - min-height: 136px; - } - - .table-row { - background-color: $color-white; - display: grid; - grid-template-columns: 1fr 43% 12px; - height: 63px; - &:not(:first-child) { - margin-top: 8px; - } - } - - .table-field { - &.name { - color: $color-gray-60; - } - - &.expiration-date { - color: $color-gray-40; - font-size: $fs14; - .content { - padding: 2px 5px; - &.expired { - background-color: $color-warning-lighter; - border-radius: $br4; - color: $color-gray-40; - } - } - } - - &.access-token-created { - word-break: break-all; - } - - &.actions { - position: relative; - } - } -} - -.access-tokens-modal { - .action-buttons { - gap: 10px; - - .cancel-button { - border: 1px solid $color-gray-30; - background: $color-canvas; - border-radius: $br3; - padding: 0.5rem 1rem; - cursor: pointer; - margin-right: 8px; - - &:hover { - background: $color-gray-20; - } - } - } - .access-token-created { - position: relative; - word-break: break-all; - - .custom-input input { - background-color: $color-success-lighter; - border: 0; - padding: 0 0 0 15px; - } - } - - .help-icon { - border: none; - height: 40px; - width: 40px; - position: absolute; - top: 0; - right: 0; - cursor: pointer; - background-color: $color-success-lighter; - - svg { - fill: $color-gray-30; - } - - &:hover { - svg { - fill: $color-gray-60; - } - } - } - - .token-created-info { - font-size: $fs12; - color: $color-gray-40; - } -} - -.dashboard-settings { - a { - color: $df-secondary; - } - .form-container { - width: 800px; - margin: 80px auto auto 120px; - form { - width: 468px; - .fields-row { - .custom-input, - .custom-select { - flex-direction: column-reverse; - label { - position: relative; - text-transform: uppercase; - color: $df-primary; - font-size: 11px; - margin-bottom: 12px; - margin-left: -4px; - } - input, - select { - background-color: $db-tertiary; - border-radius: 8px; - border-color: transparent; - color: $df-primary; - padding: 0 15px; - &:focus { - outline: 1px solid $da-primary; - } - ::placeholder { - color: $df-secondary; - } - } - .help-icon { - bottom: 12px; - top: auto; - svg { - fill: $df-secondary; - } - } - &.disabled { - input { - background-color: $db-primary; - border-color: $db-cuaternary; - color: $df-secondary; - } - } - .input-container { - background-color: $db-tertiary; - border-radius: 8px; - border-color: transparent; - margin-top: 22px; - .main-content { - label { - position: absolute; - top: -24px; - } - span { - color: $df-primary; - } - } - &:focus { - border: 1px solid $da-primary; - } - } - textarea { - border-radius: 8px; - padding: 12px 14px; - background-color: $db-tertiary; - color: $df-primary; - border: none; - &:focus { - outline: 1px solid $da-primary; - } - } - } - } - .field-title { - color: $df-primary; - } - .field-title:not(:first-child) { - margin-top: 64px; - } - - .field-text { - color: $df-secondary; - } - button, - .btn-secondary { - width: 100%; - font-size: 11px; - text-transform: uppercase; - background-color: $db-tertiary; - color: $df-primary; - &:hover { - color: $da-primary; - background-color: $db-cuaternary; - } - } - hr { - display: none; - } - } - .links { - margin-top: 12px; - } - } -} +@use "./profile" as *; diff --git a/frontend/src/app/main/ui/settings/password.cljs b/frontend/src/app/main/ui/settings/password.cljs index 27eb69a123..6dd7f7f4f8 100644 --- a/frontend/src/app/main/ui/settings/password.cljs +++ b/frontend/src/app/main/ui/settings/password.cljs @@ -83,7 +83,7 @@ [:& fm/form {:class (stl/css :password-form) :on-submit on-submit :form form} - [:h2 (t locale "dashboard.password-change")] + [:div {:class (stl/css :fields-row)} [:& fm/input {:type "password" @@ -144,8 +144,9 @@ #(dom/set-html-title (tr "title.settings.password"))) (if new-css-system - [:section {:class (stl/css :dashboard-settings :form-container)} + [:section {:class (stl/css :dashboard-settings)} [:div {:class (stl/css :form-container)} + [:h2 (t locale "dashboard.password-change")] [:& password-form {:locale locale}]]] ;; old diff --git a/frontend/src/app/main/ui/settings/password.scss b/frontend/src/app/main/ui/settings/password.scss index aa7e88cbca..474e96838f 100644 --- a/frontend/src/app/main/ui/settings/password.scss +++ b/frontend/src/app/main/ui/settings/password.scss @@ -1,642 +1,7 @@ -@import "common/dependencies/colors"; +// 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 -$br3: 3px; -$br4: 4px; -$br8: 8px; -$br6: 6px; -$fs12: 0.75rem; -$fs14: 0.875rem; -$fs16: 1rem; -$fs18: 1.125rem; -$fs22: 1.375rem; -$fs24: 1.5rem; -$fs36: 2.25rem; -$fw400: 400; -$fw500: 500; -$fw600: 600; -$fw700: 700; -$lh-088: 0.88; -$lh-115: 1.15; // original $title-lh-sm -$lh-500: 5; // original $title-lh-sm -$size-1: 0.25rem; -$size-2: 0.5rem; -$size-4: 1rem; -$size-5: 1.5rem; -$size-6: 2rem; - -.form-container, -.generic-form { - display: flex; - justify-content: center; - flex-direction: column; - - .forms-container { - display: flex; - margin-top: 40px; - width: 536px; - justify-content: center; - } - - form { - display: flex; - flex-direction: column; - // flex-basis: 368px; - } - - .fields-row { - margin-bottom: 20px; - flex-direction: column; - - .options { - display: flex; - justify-content: flex-end; - font-size: $fs14; - margin-top: 13px; - } - } - - .field { - margin-bottom: 20px; - } - - h1 { - font-size: $fs36; - color: #2c233e; - margin-bottom: 20px; - } - - .subtitle { - font-size: $fs24; - color: #2c233e; - margin-bottom: 20px; - } - - .notification-icon { - justify-content: center; - display: flex; - margin-bottom: 3rem; - - svg { - fill: $color-gray-60; - height: 40%; - width: 40%; - } - } - - .notification-text { - font-size: $fs18; - color: $color-gray-60; - margin-bottom: 20px; - } - - .notification-text-email { - background: $color-gray-10; - border-radius: $br3; - color: $color-gray-60; - font-size: $fs18; - font-weight: $fw500; - margin: 1.5rem 0 2.5rem 0; - padding: 1rem; - text-align: center; - } - - h2 { - font-size: $fs24; - color: $color-gray-60; - // height: 40px; - display: flex; - align-items: center; - } - - a { - &:hover { - text-decoration: underline; - } - } - - p { - color: $color-gray-60; - } - - hr { - border-color: $color-gray-20; - } -} - -.dashboard-header { - display: flex; - align-items: center; - justify-content: space-between; - background-color: $color-white; - height: 63px; - padding: $size-1 $size-4 $size-1 $size-2; - position: relative; - z-index: 10; - user-select: none; - &.team { - display: grid; - grid-template-columns: 20% 1fr 20%; - } - - .element-name { - margin-right: $size-2; - } - - .btn-secondary { - flex-shrink: 0; - z-index: 10; - height: 32px; - svg { - height: 16px; - width: 16px; - } - } - - svg { - fill: $color-black; - height: 14px; - margin-right: $size-1; - width: 14px; - } - - nav { - display: flex; - align-items: flex-end; - justify-content: center; - z-index: 1; - - ul { - display: flex; - font-size: $fs14; - justify-content: center; - margin: 0; - } - - li { - a { - display: flex; - align-items: center; - flex-basis: 140px; - border-bottom: 3px solid transparent; - color: $color-gray-30; - height: 40px; - padding: $size-1 $size-5; - font-weight: $fw400; - &:hover { - color: $color-black; - text-decoration: none; - } - } - - &.active { - a { - color: $color-black; - border-color: $color-primary; - } - } - } - } - - .dashboard-title { - display: flex; - align-items: center; - margin-left: 13px; - - h1 { - color: $color-black; - display: flex; - flex-shrink: 0; - font-size: $fs22; - font-weight: $fw600; - z-index: 10; - user-select: all; - } - - .context-menu.is-open { - margin-top: 10px; - } - } - - .icon { - display: flex; - align-items: center; - cursor: pointer; - margin-left: $size-2; - z-index: 10; - - svg { - fill: $color-gray-40; - width: 15px; - height: 15px; - - &:hover { - fill: $color-primary-dark; - } - } - } - - .dashboard-buttons { - display: flex; - justify-content: flex-end; - align-items: center; - } - - .dashboard-header-actions { - display: flex; - } - - .pin-icon { - margin: 0 $size-2 0 $size-5; - background-color: transparent; - border: none; - svg { - fill: $color-gray-20; - } - - &.active { - svg { - fill: $color-gray-50; - } - } - } -} - -.dashboard-settings { - display: flex; - width: 100%; - justify-content: center; - align-items: center; - - .form-container { - margin-top: 50px; - display: flex; - max-width: 368px; - margin-bottom: 2rem; - width: 100%; - - &.two-columns { - max-width: 536px; - justify-content: space-between; - flex-direction: row; - } - - h2 { - margin-bottom: 1rem; - } - } - - .avatar-form { - display: flex; - flex-direction: column; - width: 120px; - min-width: 120px; - - img { - border-radius: 50%; - flex-shrink: 0; - height: 120px; - margin-right: $size-4; - width: 120px; - } - - .image-change-field { - position: relative; - width: 120px; - height: 120px; - - .update-overlay { - opacity: 0; - cursor: pointer; - position: absolute; - width: 121px; - height: 121px; - border-radius: 50%; - font-size: $fs24; - color: $color-white; - line-height: $lh-500; // Original value was 120px; 120px/24px = 500% => $lh-500 - text-align: center; - background: $color-primary-dark; - z-index: 14; - } - - input[type="file"] { - width: 120px; - height: 120px; - position: absolute; - opacity: 0; - cursor: pointer; - top: 0; - z-index: 15; - } - - &:hover { - .update-overlay { - opacity: 0.8; - } - } - } - } - - .profile-form { - display: flex; - flex-direction: column; - max-width: 368px; - width: 100%; - - .newsletter-subs { - border-bottom: 1px solid $color-gray-20; - border-top: 1px solid $color-gray-20; - padding: 30px 0; - margin-bottom: 31px; - - .newsletter-title { - font-family: "worksans", sans-serif; - color: $color-gray-30; - font-size: $fs14; - } - - label { - font-family: "worksans", sans-serif; - color: $color-gray-60; - font-size: $fs12; - margin-right: -17px; - margin-bottom: 13px; - } - - .info { - font-family: "worksans", sans-serif; - color: $color-gray-30; - font-size: $fs12; - margin-bottom: 8px; - } - - .input-checkbox label { - align-items: flex-start; - } - } - } - - .options-form, - .password-form { - h2 { - font-size: $fs14; - margin-bottom: 20px; - } - } -} - -.dashboard-access-tokens { - display: flex; - flex-direction: column; - align-items: center; - - .access-tokens-hero-container { - max-width: 1000px; - width: 100%; - display: flex; - flex-direction: column; - } - - .access-tokens-hero { - font-size: $fs14; - padding: $size-6; - background-color: $color-white; - margin-top: $size-6; - display: flex; - justify-content: space-between; - - .desc { - width: 80%; - color: $color-gray-40; - h2 { - margin-bottom: $size-4; - color: $color-black; - } - p { - font-size: $fs16; - } - } - - .btn-primary { - flex-shrink: 0; - } - } - - .access-tokens-empty { - text-align: center; - max-width: 1000px; - width: 100%; - padding: $size-6; - display: flex; - flex-direction: column; - justify-content: center; - align-items: center; - border: 1px dashed $color-gray-20; - color: $color-gray-40; - margin-top: 12px; - min-height: 136px; - } - - .table-row { - background-color: $color-white; - display: grid; - grid-template-columns: 1fr 43% 12px; - height: 63px; - &:not(:first-child) { - margin-top: 8px; - } - } - - .table-field { - &.name { - color: $color-gray-60; - } - - &.expiration-date { - color: $color-gray-40; - font-size: $fs14; - .content { - padding: 2px 5px; - &.expired { - background-color: $color-warning-lighter; - border-radius: $br4; - color: $color-gray-40; - } - } - } - - &.access-token-created { - word-break: break-all; - } - - &.actions { - position: relative; - } - } -} - -.access-tokens-modal { - .action-buttons { - gap: 10px; - - .cancel-button { - border: 1px solid $color-gray-30; - background: $color-canvas; - border-radius: $br3; - padding: 0.5rem 1rem; - cursor: pointer; - margin-right: 8px; - - &:hover { - background: $color-gray-20; - } - } - } - .access-token-created { - position: relative; - word-break: break-all; - - .custom-input input { - background-color: $color-success-lighter; - border: 0; - padding: 0 0 0 15px; - } - } - - .help-icon { - border: none; - height: 40px; - width: 40px; - position: absolute; - top: 0; - right: 0; - cursor: pointer; - background-color: $color-success-lighter; - - svg { - fill: $color-gray-30; - } - - &:hover { - svg { - fill: $color-gray-60; - } - } - } - - .token-created-info { - font-size: $fs12; - color: $color-gray-40; - } -} - -.dashboard-settings { - a { - color: $df-secondary; - } - .form-container { - width: 800px; - margin: 80px auto auto 120px; - form { - width: 468px; - .fields-row { - .custom-input, - .custom-select { - flex-direction: column-reverse; - label { - position: relative; - text-transform: uppercase; - color: $df-primary; - font-size: 11px; - margin-bottom: 12px; - margin-left: -4px; - } - input, - select { - background-color: $db-tertiary; - border-radius: 8px; - border-color: transparent; - color: $df-primary; - padding: 0 15px; - &:focus { - outline: 1px solid $da-primary; - } - ::placeholder { - color: $df-secondary; - } - } - .help-icon { - bottom: 12px; - top: auto; - svg { - fill: $df-secondary; - } - } - &.disabled { - input { - background-color: $db-primary; - border-color: $db-cuaternary; - color: $df-secondary; - } - } - .input-container { - background-color: $db-tertiary; - border-radius: 8px; - border-color: transparent; - margin-top: 22px; - .main-content { - label { - position: absolute; - top: -24px; - } - span { - color: $df-primary; - } - } - &:focus { - border: 1px solid $da-primary; - } - } - textarea { - border-radius: 8px; - padding: 12px 14px; - background-color: $db-tertiary; - color: $df-primary; - border: none; - &:focus { - outline: 1px solid $da-primary; - } - } - } - } - .field-title { - color: $df-primary; - } - .field-title:not(:first-child) { - margin-top: 64px; - } - - .field-text { - color: $df-secondary; - } - button, - .btn-secondary { - width: 100%; - font-size: 11px; - text-transform: uppercase; - background-color: $db-tertiary; - color: $df-primary; - &:hover { - color: $da-primary; - background-color: $db-cuaternary; - } - } - hr { - display: none; - } - } - .links { - margin-top: 12px; - } - } -} +@use "./profile" as *; diff --git a/frontend/src/app/main/ui/settings/profile.cljs b/frontend/src/app/main/ui/settings/profile.cljs index fc98794451..8dfb6b87b9 100644 --- a/frontend/src/app/main/ui/settings/profile.cljs +++ b/frontend/src/app/main/ui/settings/profile.cljs @@ -61,7 +61,8 @@ :name :fullname :label (tr "dashboard.your-name")}]] - [:div {:class (stl/css :fields-row)} + [:div {:class (stl/css :fields-row) + :on-click #(modal/show! :change-email {})} [:& fm/input {:type "email" :name :email @@ -76,7 +77,8 @@ [:> fm/submit-button* {:label (tr "dashboard.save-settings") - :disabled (empty? (:touched @form))}] + :disabled (empty? (:touched @form)) + :className (stl/css :btn-primary)}] [:div {:class (stl/css :links)} [:div {:class (stl/css :link-item)} @@ -160,7 +162,8 @@ (dom/set-html-title (tr "title.settings.profile"))) (if new-css-system [:div {:class (stl/css :dashboard-settings)} - [:div {:class (stl/css :form-container :two-columns)} + [:div {:class (stl/css :form-container)} + [:h2 (tr "labels.profile")] [:& profile-photo-form] [:& profile-form]]] @@ -170,4 +173,3 @@ [:& profile-photo-form] [:& profile-form]]]))) - diff --git a/frontend/src/app/main/ui/settings/profile.scss b/frontend/src/app/main/ui/settings/profile.scss index aa7e88cbca..dc13b02310 100644 --- a/frontend/src/app/main/ui/settings/profile.scss +++ b/frontend/src/app/main/ui/settings/profile.scss @@ -1,111 +1,217 @@ -@import "common/dependencies/colors"; +// 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 -$br3: 3px; -$br4: 4px; -$br8: 8px; -$br6: 6px; -$fs12: 0.75rem; -$fs14: 0.875rem; -$fs16: 1rem; -$fs18: 1.125rem; -$fs22: 1.375rem; -$fs24: 1.5rem; -$fs36: 2.25rem; -$fw400: 400; -$fw500: 500; -$fw600: 600; -$fw700: 700; -$lh-088: 0.88; -$lh-115: 1.15; // original $title-lh-sm -$lh-500: 5; // original $title-lh-sm -$size-1: 0.25rem; -$size-2: 0.5rem; -$size-4: 1rem; -$size-5: 1.5rem; -$size-6: 2rem; +@use "common/refactor/common-refactor" as *; -.form-container, -.generic-form { +.dashboard-settings { + display: flex; + width: 100%; + justify-content: center; + align-items: center; + a { + color: $df-secondary; + } +} + +.form-container { display: flex; justify-content: center; flex-direction: column; - - .forms-container { - display: flex; - margin-top: 40px; - width: 536px; - justify-content: center; - } + max-width: $s-368; + margin-bottom: $s-32; + width: $s-580; + margin: $s-80 auto auto $s-120; + justify-content: center; form { display: flex; flex-direction: column; - // flex-basis: 368px; + width: $s-500; + + .btn-secondary { + width: 100%; + font-size: $fs-11; + text-transform: uppercase; + background-color: $db-tertiary; + color: $df-primary; + &:hover { + color: $da-primary; + background-color: $db-cuaternary; + } + } + hr { + display: none; + } } .fields-row { - margin-bottom: 20px; + margin-bottom: $s-20; flex-direction: column; .options { display: flex; justify-content: flex-end; - font-size: $fs14; - margin-top: 13px; + font-size: $fs-14; + margin-top: $s-12; + } + + :global(input) { + height: $s-40; } } .field { - margin-bottom: 20px; + margin-bottom: $s-20; + } + + .field-title { + color: $df-primary; + + &:not(:first-child) { + margin-top: $s-64; + } + } + + .field-text { + color: $df-secondary; + } + + .custom-input, + .custom-select { + flex-direction: column-reverse; + label { + position: relative; + text-transform: uppercase; + color: $df-primary; + font-size: $fs-11; + margin-bottom: $s-12; + margin-left: calc(-1 * $s-4); + } + input, + select { + background-color: $db-tertiary; + border-radius: $br-8; + border-color: transparent; + color: $df-primary; + padding: 0 $s-16; + &:focus { + outline: $s-1 solid $da-primary; + } + ::placeholder { + color: $df-secondary; + } + } + .help-icon { + bottom: $s-12; + top: auto; + svg { + fill: $df-secondary; + } + } + &.disabled { + input { + background-color: $db-primary; + border-color: $db-cuaternary; + color: $df-secondary; + } + } + .input-container { + background-color: $db-tertiary; + border-radius: $br-8; + border-color: transparent; + margin-top: $s-24; + .main-content { + label { + position: absolute; + top: calc(-1 * $s-24); + } + span { + color: $df-primary; + } + } + &:focus { + border: $s-1 solid $da-primary; + } + } + textarea { + border-radius: $br-8; + padding: $s-12 $s-16; + background-color: $db-tertiary; + color: $df-primary; + border: none; + &:focus { + outline: $s-1 solid $da-primary; + } + } + } + + &.two-columns { + max-width: $s-520; + justify-content: space-between; + flex-direction: row; } h1 { - font-size: $fs36; - color: #2c233e; - margin-bottom: 20px; + font-size: $fs-36; + color: $db-tertiary; + margin-bottom: $s-20; } .subtitle { - font-size: $fs24; - color: #2c233e; - margin-bottom: 20px; + font-size: $fs-24; + color: $db-tertiary; + margin-bottom: $s-20; } .notification-icon { justify-content: center; display: flex; - margin-bottom: 3rem; + margin-bottom: $s-48; svg { - fill: $color-gray-60; + fill: $db-primary; height: 40%; width: 40%; } } .notification-text { - font-size: $fs18; - color: $color-gray-60; - margin-bottom: 20px; + font-size: $fs-16; + color: $db-primary; + margin-bottom: $s-20; } .notification-text-email { - background: $color-gray-10; - border-radius: $br3; - color: $color-gray-60; - font-size: $fs18; + background: $df-primary; + border-radius: $br-4; + color: $db-primary; + font-size: $fs-16; font-weight: $fw500; - margin: 1.5rem 0 2.5rem 0; - padding: 1rem; + margin: $s-24 0 $s-40 0; + padding: $s-16; text-align: center; } h2 { - font-size: $fs24; - color: $color-gray-60; - // height: 40px; + font-size: $fs-24; + font-weight: $fw400; + color: $df-primary; display: flex; align-items: center; + margin: $s-16 0; + } + + h3 { + font-size: $fs-12; + font-weight: $fw400; + color: $df-primary; + display: flex; + align-items: center; + margin: $s-8 0; + text-transform: uppercase; } a { @@ -115,528 +221,115 @@ $size-6: 2rem; } p { - color: $color-gray-60; + color: $db-primary; } hr { - border-color: $color-gray-20; + border-color: $df-secondary; + } + + .links { + margin-top: $s-12; } } -.dashboard-header { - display: flex; - align-items: center; - justify-content: space-between; - background-color: $color-white; - height: 63px; - padding: $size-1 $size-4 $size-1 $size-2; - position: relative; - z-index: 10; - user-select: none; - &.team { - display: grid; - grid-template-columns: 20% 1fr 20%; - } - - .element-name { - margin-right: $size-2; - } - - .btn-secondary { - flex-shrink: 0; - z-index: 10; - height: 32px; - svg { - height: 16px; - width: 16px; - } - } - - svg { - fill: $color-black; - height: 14px; - margin-right: $size-1; - width: 14px; - } - - nav { - display: flex; - align-items: flex-end; - justify-content: center; - z-index: 1; - - ul { - display: flex; - font-size: $fs14; - justify-content: center; - margin: 0; - } - - li { - a { - display: flex; - align-items: center; - flex-basis: 140px; - border-bottom: 3px solid transparent; - color: $color-gray-30; - height: 40px; - padding: $size-1 $size-5; - font-weight: $fw400; - &:hover { - color: $color-black; - text-decoration: none; - } - } - - &.active { - a { - color: $color-black; - border-color: $color-primary; - } - } - } - } - - .dashboard-title { - display: flex; - align-items: center; - margin-left: 13px; - - h1 { - color: $color-black; - display: flex; - flex-shrink: 0; - font-size: $fs22; - font-weight: $fw600; - z-index: 10; - user-select: all; - } - - .context-menu.is-open { - margin-top: 10px; - } - } - - .icon { - display: flex; - align-items: center; - cursor: pointer; - margin-left: $size-2; - z-index: 10; - - svg { - fill: $color-gray-40; - width: 15px; - height: 15px; - - &:hover { - fill: $color-primary-dark; - } - } - } - - .dashboard-buttons { - display: flex; - justify-content: flex-end; - align-items: center; - } - - .dashboard-header-actions { - display: flex; - } - - .pin-icon { - margin: 0 $size-2 0 $size-5; - background-color: transparent; - border: none; - svg { - fill: $color-gray-20; - } - - &.active { - svg { - fill: $color-gray-50; - } - } - } -} - -.dashboard-settings { - display: flex; - width: 100%; - justify-content: center; - align-items: center; - - .form-container { - margin-top: 50px; - display: flex; - max-width: 368px; - margin-bottom: 2rem; - width: 100%; - - &.two-columns { - max-width: 536px; - justify-content: space-between; - flex-direction: row; - } - - h2 { - margin-bottom: 1rem; - } - } - - .avatar-form { - display: flex; - flex-direction: column; - width: 120px; - min-width: 120px; - - img { - border-radius: 50%; - flex-shrink: 0; - height: 120px; - margin-right: $size-4; - width: 120px; - } - - .image-change-field { - position: relative; - width: 120px; - height: 120px; - - .update-overlay { - opacity: 0; - cursor: pointer; - position: absolute; - width: 121px; - height: 121px; - border-radius: 50%; - font-size: $fs24; - color: $color-white; - line-height: $lh-500; // Original value was 120px; 120px/24px = 500% => $lh-500 - text-align: center; - background: $color-primary-dark; - z-index: 14; - } - - input[type="file"] { - width: 120px; - height: 120px; - position: absolute; - opacity: 0; - cursor: pointer; - top: 0; - z-index: 15; - } - - &:hover { - .update-overlay { - opacity: 0.8; - } - } - } - } - - .profile-form { - display: flex; - flex-direction: column; - max-width: 368px; - width: 100%; - - .newsletter-subs { - border-bottom: 1px solid $color-gray-20; - border-top: 1px solid $color-gray-20; - padding: 30px 0; - margin-bottom: 31px; - - .newsletter-title { - font-family: "worksans", sans-serif; - color: $color-gray-30; - font-size: $fs14; - } - - label { - font-family: "worksans", sans-serif; - color: $color-gray-60; - font-size: $fs12; - margin-right: -17px; - margin-bottom: 13px; - } - - .info { - font-family: "worksans", sans-serif; - color: $color-gray-30; - font-size: $fs12; - margin-bottom: 8px; - } - - .input-checkbox label { - align-items: flex-start; - } - } - } - - .options-form, - .password-form { - h2 { - font-size: $fs14; - margin-bottom: 20px; - } - } -} - -.dashboard-access-tokens { +form.avatar-form { display: flex; flex-direction: column; - align-items: center; + width: $s-148; + height: $s-148; + margin: $s-16 0; - .access-tokens-hero-container { - max-width: 1000px; + img { + border-radius: 50%; + flex-shrink: 0; + height: 100%; + margin-right: $s-16; width: 100%; - display: flex; - flex-direction: column; - } - - .access-tokens-hero { - font-size: $fs14; - padding: $size-6; - background-color: $color-white; - margin-top: $size-6; - display: flex; - justify-content: space-between; - - .desc { - width: 80%; - color: $color-gray-40; - h2 { - margin-bottom: $size-4; - color: $color-black; - } - p { - font-size: $fs16; - } - } - - .btn-primary { - flex-shrink: 0; - } - } - - .access-tokens-empty { - text-align: center; - max-width: 1000px; - width: 100%; - padding: $size-6; - display: flex; - flex-direction: column; - justify-content: center; - align-items: center; - border: 1px dashed $color-gray-20; - color: $color-gray-40; - margin-top: 12px; - min-height: 136px; - } - - .table-row { - background-color: $color-white; - display: grid; - grid-template-columns: 1fr 43% 12px; - height: 63px; - &:not(:first-child) { - margin-top: 8px; - } - } - - .table-field { - &.name { - color: $color-gray-60; - } - - &.expiration-date { - color: $color-gray-40; - font-size: $fs14; - .content { - padding: 2px 5px; - &.expired { - background-color: $color-warning-lighter; - border-radius: $br4; - color: $color-gray-40; - } - } - } - - &.access-token-created { - word-break: break-all; - } - - &.actions { - position: relative; - } } } -.access-tokens-modal { - .action-buttons { - gap: 10px; +.image-change-field { + position: relative; + width: 100%; + height: 100%; - .cancel-button { - border: 1px solid $color-gray-30; - background: $color-canvas; - border-radius: $br3; - padding: 0.5rem 1rem; - cursor: pointer; - margin-right: 8px; - - &:hover { - background: $color-gray-20; - } - } - } - .access-token-created { - position: relative; - word-break: break-all; - - .custom-input input { - background-color: $color-success-lighter; - border: 0; - padding: 0 0 0 15px; - } - } - - .help-icon { - border: none; - height: 40px; - width: 40px; - position: absolute; - top: 0; - right: 0; + .update-overlay { + opacity: 0; cursor: pointer; - background-color: $color-success-lighter; - - svg { - fill: $color-gray-30; - } - - &:hover { - svg { - fill: $color-gray-60; - } - } + position: absolute; + width: 100%; + height: 100%; + border-radius: 50%; + font-size: $fs-24; + color: $df-primary; + line-height: 6; + text-align: center; + background: $da-tertiary; + z-index: 14; } - .token-created-info { - font-size: $fs12; - color: $color-gray-40; + input[type="file"] { + width: 100%; + height: 100%; + position: absolute; + opacity: 0; + cursor: pointer; + top: 0; + z-index: 15; + } + + &:hover { + .update-overlay { + opacity: 0.8; + } } } -.dashboard-settings { - a { +.profile-form { + display: flex; + flex-direction: column; + max-width: $s-368; + width: 100%; +} + +.newsletter-subs { + border-bottom: $s-1 solid $df-secondary; + border-top: $s-1 solid $df-secondary; + padding: $s-32 0; + margin-bottom: $s-32; + + .newsletter-title { + font-family: "worksans", sans-serif; color: $df-secondary; + font-size: $fs-14; } - .form-container { - width: 800px; - margin: 80px auto auto 120px; - form { - width: 468px; - .fields-row { - .custom-input, - .custom-select { - flex-direction: column-reverse; - label { - position: relative; - text-transform: uppercase; - color: $df-primary; - font-size: 11px; - margin-bottom: 12px; - margin-left: -4px; - } - input, - select { - background-color: $db-tertiary; - border-radius: 8px; - border-color: transparent; - color: $df-primary; - padding: 0 15px; - &:focus { - outline: 1px solid $da-primary; - } - ::placeholder { - color: $df-secondary; - } - } - .help-icon { - bottom: 12px; - top: auto; - svg { - fill: $df-secondary; - } - } - &.disabled { - input { - background-color: $db-primary; - border-color: $db-cuaternary; - color: $df-secondary; - } - } - .input-container { - background-color: $db-tertiary; - border-radius: 8px; - border-color: transparent; - margin-top: 22px; - .main-content { - label { - position: absolute; - top: -24px; - } - span { - color: $df-primary; - } - } - &:focus { - border: 1px solid $da-primary; - } - } - textarea { - border-radius: 8px; - padding: 12px 14px; - background-color: $db-tertiary; - color: $df-primary; - border: none; - &:focus { - outline: 1px solid $da-primary; - } - } - } - } - .field-title { - color: $df-primary; - } - .field-title:not(:first-child) { - margin-top: 64px; - } - .field-text { - color: $df-secondary; - } - button, - .btn-secondary { - width: 100%; - font-size: 11px; - text-transform: uppercase; - background-color: $db-tertiary; - color: $df-primary; - &:hover { - color: $da-primary; - background-color: $db-cuaternary; - } - } - hr { - display: none; - } - } - .links { - margin-top: 12px; - } + label { + font-family: "worksans", sans-serif; + color: $db-primary; + font-size: $fs-12; + margin-right: calc(-1 * $s-16); + margin-bottom: $s-12; + } + + .info { + color: $df-secondary; + font-size: $fs-12; + margin-bottom: $s-8; + } + + .input-checkbox label { + align-items: flex-start; } } + +.btn-secondary { + @extend .button-secondary; + height: $s-32; +} + +.btn-primary { + @extend .button-primary; + height: $s-32; +} diff --git a/frontend/src/app/main/ui/settings/sidebar.cljs b/frontend/src/app/main/ui/settings/sidebar.cljs index 4edbc733f7..cb13feab08 100644 --- a/frontend/src/app/main/ui/settings/sidebar.cljs +++ b/frontend/src/app/main/ui/settings/sidebar.cljs @@ -82,31 +82,26 @@ [:ul {:class (stl/css :sidebar-nav :no-overflow)} [:li {:class (when profile? (stl/css :current)) :on-click go-settings-profile} - i/user [:span {:class (stl/css :element-title)} (tr "labels.profile")]] [:li {:class (when password? (stl/css :current)) :on-click go-settings-password} - i/lock [:span {:class (stl/css :element-title)} (tr "labels.password")]] [:li {:class (when options? (stl/css :current)) :on-click go-settings-options :data-test "settings-profile"} - i/tree [:span {:class (stl/css :element-title)} (tr "labels.settings")]] (when (contains? cf/flags :access-tokens) [:li {:class (when access-tokens? (stl/css :current)) :on-click go-settings-access-tokens :data-test "settings-access-tokens"} - i/icon-key [:span {:class (stl/css :element-title)} (tr "labels.access-tokens")]]) [:hr] [:li {:on-click show-release-notes :data-test "release-notes"} - i/pencil [:span {:class (stl/css :element-title)} (tr "labels.release-notes")]] (when (contains? cf/flags :user-feedback) diff --git a/frontend/src/app/main/ui/settings/sidebar.scss b/frontend/src/app/main/ui/settings/sidebar.scss index bc77f93fb6..263ff24af2 100644 --- a/frontend/src/app/main/ui/settings/sidebar.scss +++ b/frontend/src/app/main/ui/settings/sidebar.scss @@ -1,33 +1,22 @@ -@import "common/dependencies/colors"; +// 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 -$fs14: 0.875rem; -$fs24: 1.5rem; -$lh-500: 5; -$fs12: 0.75rem; -$fs16: 1rem; -$fw400: 400; -$size-2: 0.5rem; -$size-3: 0.75rem; -$size-4: 1rem; -$size-6: 2rem; -$br3: 3px; -$br4: 4px; -$br5: 5px; -$fw700: 700; +@use "common/refactor/common-refactor.scss" as *; .dashboard-sidebar { - grid-row: 1 / span 2; - grid-column: 1 / span 2; - background-color: $db-primary; - border-right: 1px solid $db-cuaternary; - margin: 0 1rem 0 0; - padding: 1rem 0 0 0; - - z-index: 1; + border-right: $s-1 solid $db-cuaternary; display: flex; flex-direction: column; + grid-column: 1 / span 2; + grid-row: 1 / span 2; height: 100%; + margin: 0 $s-16 0 0; + padding: $s-16 0 0 0; + z-index: 1; } .sidebar-content { @@ -39,884 +28,132 @@ $fw700: 700; hr { border-color: transparent; - margin: 0.8rem 15px; - } - - .back-to-dashboard { - .icon svg { - fill: $df-secondary; - } - .text { - color: $df-primary; - } + margin: $s-12 $s-16; } } -.dashboard-sidebar { - background-color: $color-white; - z-index: 1; +.sidebar-nav { display: flex; flex-direction: column; - height: 100%; - padding-top: $size-2; + margin: 0; + overflow-y: auto; + user-select: none; - .sidebar-content { - display: flex; - flex-direction: column; - height: 100%; - overflow-y: auto; - padding: 0; - - //hr { - // border-color: $color-gray-10; - // margin: 1rem 15px; - //} + &.no-overflow { + overflow: unset; } - .sidebar-team-switch { - position: relative; - display: flex; - margin: 5px 15px; - - .teams-dropdown { - left: 0; - top: 50px; - z-index: 12; - max-height: 30rem; - min-width: 234px; - overflow-y: auto; - } - - .options-dropdown { - right: 2px; - top: 50px; - z-index: 12; - max-height: 30rem; - min-width: 162px; - } - - .switch-content { - height: 40px; - display: flex; - width: 100%; - border: 1px solid $color-gray-10; - border-radius: $br5; - align-items: center; - } - - .switch-options { - display: flex; - max-width: 22px; - min-width: 28px; - border-left: 1px solid $color-gray-10; - justify-content: center; - align-items: center; - cursor: pointer; - background-color: transparent; - border: none; - svg { - width: 15px; - height: 13px; - fill: $color-gray-60; - } - } - - .current-team { - cursor: pointer; - display: flex; - align-items: center; - flex-grow: 1; - font-size: $fs14; - padding: 0px 10px; - background-color: transparent; - border: none; - } - - .team-name { - flex-grow: 1; - display: flex; - height: 40px; - align-items: center; - - &.action { - .team-icon { - border-radius: 50%; - background-color: $color-gray-10; - height: 24px; - margin-right: 10px; - padding: 6px; - width: 24px; - - svg { - height: 12px; - width: 12px; - } - } - - &:hover { - .team-icon { - background-color: $color-primary; - } - } - - .team-text { - width: 150px; - } - } - - .team-icon { - display: flex; - align-items: center; - padding-right: 10px; - - svg { - width: 23px; - height: 23px; - fill: $color-gray-60; - } - - img { - border-radius: 50%; - flex-shrink: 0; - height: 23px; - width: 23px; - } - } - - .team-text { - color: $color-gray-60; - // @include text-ellipsis; - width: 130px; - text-align: left; - } - - .icon { - margin-left: auto; - svg { - fill: $color-gray-60; - } - } - } - - .switch-icon { - display: flex; - align-items: center; - justify-content: center; - svg { - width: 10px; - height: 10px; - fill: $color-gray-60; - } - } - } - - .sidebar-empty-placeholder { - padding: 10px 12px; - color: $color-gray-30; - display: flex; - align-items: flex-start; - - .icon { - padding: 0px 10px; - svg { - fill: $color-gray-30; - width: 12px; - height: 12px; - } - } - .text { - font-size: $fs12; - } - } - - .sidebar-nav { - display: flex; - flex-direction: column; - overflow-y: auto; - margin: 0; - user-select: none; - - // TODO: should be deprecated / unclear name - &.dashboard-common { - overflow: unset; - } - - &.no-overflow { - overflow: unset; - } - - & > li { - align-items: center; - cursor: pointer; - display: flex; - flex-shrink: 0; - padding: $size-2; - a { - font-weight: $fw400; - width: 100%; - &:hover { - text-decoration: none; - } - } - - svg { - fill: $color-black; - margin-right: 8px; - height: $size-3; - width: $size-3; - } - - span.element-title { - color: $color-gray-60; - font-size: $fs14; - overflow: hidden; - text-overflow: ellipsis; - white-space: nowrap; - } - - &::before { - background-color: transparent; - border-radius: $br3; - content: ""; - height: 26px; - margin-right: $size-2; - width: 4px; - } - - &.recent-projects { - svg { - fill: $color-white; - } - } - - & .edit-wrapper { - border: 1px solid $color-gray-10; - border-radius: $br3; - display: flex; - width: 100%; - } - - input.element-title { - border: 0; - height: 30px; - padding: 5px; - margin: 0; - width: 100%; - background-color: $color-white; - } - - .close { - background-color: $color-white; - cursor: pointer; - padding-left: 5px; - - svg { - fill: $color-gray-30; - height: 15px; - transform: rotate(45deg) translateY(7px); - width: 15px; - margin: 0; - } - } - - .element-subtitle { - color: $color-gray-20; - font-style: italic; - } - - &:hover { - &::before { - background-color: $color-gray-10; - } - } - - &.current { - a { - font-weight: $fw700; - } - - &::before { - background-color: $color-primary; - } - } - - &.dragging { - //background-color: color.adjust($color-primary, $alpha: -0.69); - } - } - } - - .sidebar-search { + li { align-items: center; - background-color: $color-white; - border: 1px solid $color-gray-10; - border-radius: $br5; - display: flex; - margin: 5px 15px; - - .input-text { - background: transparent; - border: 0; - color: $color-gray-60; - font-size: $fs14; - padding: 6px; - margin: 0; - max-width: 195px; - width: 100%; - height: 40px; - } - - &:focus, - &:focus-within { - border-color: $color-black; - } - - .search, - .clear-search { - align-items: center; - cursor: pointer; - display: flex; - height: 22px; - margin-left: auto; - padding: 0 $size-2; - width: 32px; - - svg { - fill: $color-gray-30; - height: 15px; - width: 15px; - } - } - - .clear-search svg { - transform: rotate(45deg); - - &:hover { - fill: $color-danger; - } - } - } - - &.profile-bar { - background-color: $color-gray-10; - - .dashboard-sidebar-inside { - display: none; - } - } -} - -.dashboard-sidebar { - &.settings { - .back-to-dashboard { - padding: 12px 18px; - font-size: $fs14; - cursor: pointer; - display: flex; - - .icon { - display: flex; - align-items: center; - margin-right: 14px; - } - - .text { - color: $color-gray-60; - } - - svg { - fill: $color-gray-60; - transform: rotate(90deg); - width: 12px; - height: 12px; - } - } - } -} - -.dashboard-settings { - display: flex; - width: 100%; - justify-content: center; - align-items: center; - - .form-container { - margin-top: 50px; - display: flex; - max-width: 368px; - margin-bottom: 2rem; - width: 100%; - - &.two-columns { - max-width: 536px; - justify-content: space-between; - flex-direction: row; - } - - h2 { - margin-bottom: 1rem; - } - } - - .avatar-form { - display: flex; - flex-direction: column; - width: 120px; - min-width: 120px; - - img { - border-radius: 50%; - flex-shrink: 0; - height: 120px; - margin-right: $size-4; - width: 120px; - } - - .image-change-field { - position: relative; - width: 120px; - height: 120px; - - .update-overlay { - opacity: 0; - cursor: pointer; - position: absolute; - width: 121px; - height: 121px; - border-radius: 50%; - font-size: $fs24; - color: $color-white; - line-height: $lh-500; // Original value was 120px; 120px/24px = 500% => $lh-500 - text-align: center; - background: $color-primary-dark; - z-index: 14; - } - - input[type="file"] { - width: 120px; - height: 120px; - position: absolute; - opacity: 0; - cursor: pointer; - top: 0; - z-index: 15; - } - - &:hover { - .update-overlay { - opacity: 0.8; - } - } - } - } - - .profile-form { - display: flex; - flex-direction: column; - max-width: 368px; - width: 100%; - - .newsletter-subs { - border-bottom: 1px solid $color-gray-20; - border-top: 1px solid $color-gray-20; - padding: 30px 0; - margin-bottom: 31px; - - .newsletter-title { - font-family: "worksans", sans-serif; - color: $color-gray-30; - font-size: $fs14; - } - - label { - font-family: "worksans", sans-serif; - color: $color-gray-60; - font-size: $fs12; - margin-right: -17px; - margin-bottom: 13px; - } - - .info { - font-family: "worksans", sans-serif; - color: $color-gray-30; - font-size: $fs12; - margin-bottom: 8px; - } - - .input-checkbox label { - align-items: flex-start; - } - } - } - - .options-form, - .password-form { - h2 { - font-size: $fs14; - margin-bottom: 20px; - } - } -} - -.dashboard-access-tokens { - display: flex; - flex-direction: column; - align-items: center; - - .access-tokens-hero-container { - max-width: 1000px; - width: 100%; - display: flex; - flex-direction: column; - } - - .access-tokens-hero { - font-size: $fs14; - padding: $size-6; - background-color: $color-white; - margin-top: $size-6; - display: flex; - justify-content: space-between; - - .desc { - width: 80%; - color: $color-gray-40; - h2 { - margin-bottom: $size-4; - color: $color-black; - } - p { - font-size: $fs16; - } - } - - .btn-primary { - flex-shrink: 0; - } - } - - .access-tokens-empty { - text-align: center; - max-width: 1000px; - width: 100%; - padding: $size-6; - display: flex; - flex-direction: column; - justify-content: center; - align-items: center; - border: 1px dashed $color-gray-20; - color: $color-gray-40; - margin-top: 12px; - min-height: 136px; - } - - .table-row { - background-color: $color-white; - display: grid; - grid-template-columns: 1fr 43% 12px; - height: 63px; - &:not(:first-child) { - margin-top: 8px; - } - } - - .table-field { - &.name { - color: $color-gray-60; - } - - &.expiration-date { - color: $color-gray-40; - font-size: $fs14; - .content { - padding: 2px 5px; - &.expired { - background-color: $color-warning-lighter; - border-radius: $br4; - color: $color-gray-40; - } - } - } - - &.access-token-created { - word-break: break-all; - } - - &.actions { - position: relative; - } - } -} - -.access-tokens-modal { - .action-buttons { - gap: 10px; - - .cancel-button { - border: 1px solid $color-gray-30; - background: $color-canvas; - border-radius: $br3; - padding: 0.5rem 1rem; - cursor: pointer; - margin-right: 8px; - - &:hover { - background: $color-gray-20; - } - } - } - .access-token-created { - position: relative; - word-break: break-all; - - .custom-input input { - background-color: $color-success-lighter; - border: 0; - padding: 0 0 0 15px; - } - } - - .help-icon { - border: none; - height: 40px; - width: 40px; - position: absolute; - top: 0; - right: 0; cursor: pointer; - background-color: $color-success-lighter; + display: flex; + flex-shrink: 0; + padding: $s-8 $s-8 $s-8 $s-24; + + a { + font-weight: $fw400; + width: 100%; + &:hover { + text-decoration: none; + } + } svg { - fill: $color-gray-30; + fill: $db-secondary; + margin-right: $s-8; + height: $s-12; + width: $s-12; + } + + span { + color: $df-secondary; + font-size: $fs-14; + overflow: hidden; + text-overflow: ellipsis; + white-space: nowrap; + } + + &::before { + display: none; + background-color: transparent; + border-radius: $br-4; + content: ""; + height: $s-24; + margin-right: $s-8; + width: $s-4; + } + + &.recent-projects { + svg { + fill: $df-primary; + } + } + + & .edit-wrapper { + border: $s-1 solid $df-primary; + border-radius: $br-4; + display: flex; + width: 100%; + } + + input.element-title { + border: 0; + height: $s-32; + padding: $s-6; + margin: 0; + width: 100%; + background-color: $df-primary; + } + + .element-subtitle { + color: $df-secondary; + font-style: italic; } &:hover { - svg { - fill: $color-gray-60; - } - } - } - - .token-created-info { - font-size: $fs12; - color: $color-gray-40; - } -} - -.dashboard-sidebar { - background-color: $db-primary; - border-right: 1px solid $db-cuaternary; - grid-row: 1 / span 2; - grid-column: 1 / span 2; - margin: 0 1rem 0 0; - padding: 1rem 0 0 0; - - .dropdown { - background-color: $db-tertiary; - border: 1px solid $db-cuaternary; - border-radius: 8px; - min-width: 252px; - - .separator { - border-color: transparent; - margin-top: 10px; - } - - li { - border-radius: 8px; - height: 40px; - margin: 5px; - - &:hover { - background-color: $db-cuaternary; + background-color: $db-cuaternary; + &::before { + background-color: $df-primary; } } - &.options-dropdown { - li { - color: $df-primary; - &.warning { - color: $color-danger; - } + &.current { + background-color: $db-cuaternary; + a { + font-weight: $fw400; + color: $da-primary; } - } - } - - .sidebar-content { - .back-to-dashboard { - .icon { - svg { - fill: $df-secondary; - } - } - .text { - color: $df-primary; - } - } - .sidebar-team-switch { - .switch-content { - background-color: $db-tertiary; - border-radius: 8px; - border-color: transparent; - height: 48px; - - .current-team { - border-right: 1px solid $db-primary; - height: 100%; - } - - svg { - fill: $df-secondary; - } - - .team-name { - .team-text { - color: $df-primary; - width: 145px; - } - } - } - } - - .teams-dropdown { - background-color: $db-tertiary; - border-radius: 8px; - border: 1px solid $db-cuaternary; - min-width: 248px; - - li { - border-radius: 8px; - height: 42px; - padding: 0 5px; - margin: 5px; - - .team-text { - color: $df-primary; - width: 165px; - } - svg { - fill: $df-secondary; - } - - &:hover { - background-color: $db-cuaternary; - .team-icon { - &.new-team { - background-color: $da-primary; - svg { - fill: $db-secondary; - } - } - } - } - - .team-icon { - &.new-team { - background-color: $db-cuaternary; - } - } - } - } - - .sidebar-search { - background-color: $db-tertiary; - border-color: transparent; - border-radius: 8px; - margin-bottom: 2rem; - margin-top: 0; - position: relative; - - .input-text { - border-radius: 8px; - color: $df-primary; - max-width: 100%; - padding: 6px 10px; - - &:focus { - border: 1px solid $da-primary; - } - } - ::placeholder { - color: $df-secondary; + span { + color: $da-primary; } - .search { - position: absolute; - top: 10px; - right: 2px; - } - } - - .sidebar-nav { - li { - padding: 0.6rem 0.6rem 0.6rem 1.4rem; - &.current { - background-color: $db-cuaternary; - a { - font-weight: 400; - span { - color: $da-primary; - } - } - span { - color: $da-primary; - } - } - &:hover { - background-color: $db-cuaternary; - } - span { - color: $df-secondary; - } - &::before { - display: none; - } - - svg { - display: none; - } - } - } - } - - .sidebar-empty-placeholder { - color: $df-secondary; - } - - // Profile sidebar - .profile-section { - background-color: $db-tertiary; - border-top: 1px solid $db-cuaternary; - - span { - color: $df-primary; - } - - .dashboard-comments-section { - border-color: transparent; - border-radius: 8px; - background-color: $db-primary; - height: 32px; - width: 32px; - - .button { - border-radius: 8px; - background-color: $db-primary; - height: 32px; - width: 32px; - - svg { - fill: $df-secondary; - } - - &:hover { - background-color: $db-cuaternary; - - svg { - fill: $da-primary; - } - } + &::before { + background-color: $da-tertiary; } } } } + +.back-to-dashboard { + padding: $s-12 $s-16; + font-size: $fs-14; + cursor: pointer; + display: flex; + + .icon { + display: flex; + align-items: center; + margin-right: $s-12; + } + + .text { + color: $df-primary; + } + + svg { + fill: $df-secondary; + transform: rotate(90deg); + width: $s-12; + height: $s-12; + } +} From 6b5c75bf6a9ac184cf961d8d4d5164dab199352b Mon Sep 17 00:00:00 2001 From: "alonso.torres" Date: Mon, 27 Nov 2023 17:41:25 +0100 Subject: [PATCH 5/6] :lipstick: Redesign error page --- frontend/gulpfile.js | 2 +- frontend/package.json | 1 + .../images/icons/logo-error-screen.svg | 3 + frontend/src/app/main/ui/icons.cljs | 1 + frontend/src/app/main/ui/static.cljs | 140 ++++++++++++------ frontend/src/app/main/ui/static.scss | 91 ++++++++++++ 6 files changed, 193 insertions(+), 45 deletions(-) create mode 100644 frontend/resources/images/icons/logo-error-screen.svg create mode 100644 frontend/src/app/main/ui/static.scss diff --git a/frontend/gulpfile.js b/frontend/gulpfile.js index 767ef69ecf..e232a4db1c 100644 --- a/frontend/gulpfile.js +++ b/frontend/gulpfile.js @@ -29,7 +29,7 @@ paths.resources = "./resources/"; paths.output = "./resources/public/"; paths.dist = "./target/dist/"; -const touchSourceOnStyleChange = true; +const touchSourceOnStyleChange = false; /*********************************************** * Marked Extensions diff --git a/frontend/package.json b/frontend/package.json index f9801e1553..38ef1334bb 100644 --- a/frontend/package.json +++ b/frontend/package.json @@ -15,6 +15,7 @@ "test:compile": "clojure -M:dev:shadow-cljs compile test --config-merge '{:autorun false}'", "lint:clj": "clj-kondo --parallel --lint src/", "lint:scss": "yarn run prettier -c resources/styles -c src/**/*.scss", + "lint:fix": "yarn run prettier -c resources/styles -c src/**/*.scss -w", "test:run": "node target/tests.js", "test:watch": "clojure -M:dev:shadow-cljs watch test", "test": "yarn run test:compile && yarn run test:run", diff --git a/frontend/resources/images/icons/logo-error-screen.svg b/frontend/resources/images/icons/logo-error-screen.svg new file mode 100644 index 0000000000..7e71215fac --- /dev/null +++ b/frontend/resources/images/icons/logo-error-screen.svg @@ -0,0 +1,3 @@ + + + diff --git a/frontend/src/app/main/ui/icons.cljs b/frontend/src/app/main/ui/icons.cljs index aff9e778fc..d6efe6e4af 100644 --- a/frontend/src/app/main/ui/icons.cljs +++ b/frontend/src/app/main/ui/icons.cljs @@ -170,6 +170,7 @@ (def lock (icon-xref :lock)) (def logo (icon-xref :penpot-logo)) (def logo-icon (icon-xref :penpot-logo-icon)) +(def logo-error-screen (icon-xref :logo-error-screen)) (def logout (icon-xref :logout)) (def lowercase (icon-xref :lowercase)) (def mail (icon-xref :mail)) diff --git a/frontend/src/app/main/ui/static.cljs b/frontend/src/app/main/ui/static.cljs index 9164f1041a..a9fa000c16 100644 --- a/frontend/src/app/main/ui/static.cljs +++ b/frontend/src/app/main/ui/static.cljs @@ -5,8 +5,11 @@ ;; Copyright (c) KALEIDOS INC (ns app.main.ui.static + (:require-macros [app.main.style :as stl]) (:require + [app.main.features :as features] [app.main.store :as st] + [app.main.ui.context :as ctx] [app.main.ui.icons :as i] [app.util.globals :as globals] [app.util.i18n :refer [tr]] @@ -17,66 +20,115 @@ (mf/defc static-header {::mf/wrap-props false} [props] - (let [children (obj/get props "children") + (let [new-css-system (mf/use-ctx ctx/new-css-system) + children (obj/get props "children") on-click (mf/use-callback #(set! (.-href globals/location) "/"))] - [:section.exception-layout - [:div.exception-header - {:on-click on-click} - i/logo] - [:div.exception-content - [:div.container children]]])) + (if new-css-system + [:section {:class (stl/css :exception-layout)} + [:div + {:class (stl/css :exception-header) + :on-click on-click} + i/logo-icon] + [:div {:class (stl/css :deco-before)} i/logo-error-screen] + + [:div {:class (stl/css :exception-content)} + [:div {:class (stl/css :container)} children]] + + [:div {:class (stl/css :deco-after)} i/logo-error-screen]] + [:section.exception-layout + [:div.exception-header + {:on-click on-click} + i/logo] + [:div.exception-content + [:div.container children]]]))) (mf/defc not-found [] - [:> static-header {} - [:div.image i/icon-empty] - [:div.main-message (tr "labels.not-found.main-message")] - [:div.desc-message (tr "labels.not-found.desc-message")]]) + (let [new-css-system (mf/use-ctx ctx/new-css-system)] + (if new-css-system + [:> static-header {} + [:div {:class (stl/css :main-message)} (tr "labels.not-found.main-message")] + [:div {:class (stl/css :desc-message)} (tr "labels.not-found.desc-message")]] + + [:> static-header {} + [:div.image i/icon-empty] + [:div.main-message (tr "labels.not-found.main-message")] + [:div.desc-message (tr "labels.not-found.desc-message")]]))) (mf/defc bad-gateway [] - [:> static-header {} - [:div.image i/icon-empty] - [:div.main-message (tr "labels.bad-gateway.main-message")] - [:div.desc-message (tr "labels.bad-gateway.desc-message")] - [:div.sign-info - [:a.btn-primary.btn-small - {:on-click (fn [] (st/emit! #(dissoc % :exception)))} - (tr "labels.retry")]]]) + (let [new-css-system (mf/use-ctx ctx/new-css-system)] + (if new-css-system + [:> static-header {} + [:div {:class (stl/css :main-message)} (tr "labels.bad-gateway.main-message")] + [:div {:class (stl/css :desc-message)} (tr "labels.bad-gateway.desc-message")] + [:div {:class (stl/css :sign-info)} + [:button + {:on-click (fn [] (st/emit! (rt/assign-exception nil)))} + (tr "labels.retry")]]] + + [:> static-header {} + [:div.image i/icon-empty] + [:div.main-message (tr "labels.bad-gateway.main-message")] + [:div.desc-message (tr "labels.bad-gateway.desc-message")] + [:div.sign-info + [:a.btn-primary.btn-small + {:on-click (fn [] (st/emit! #(dissoc % :exception)))} + (tr "labels.retry")]]]))) (mf/defc service-unavailable [] - [:> static-header {} - [:div.image i/icon-empty] - [:div.main-message (tr "labels.service-unavailable.main-message")] - [:div.desc-message (tr "labels.service-unavailable.desc-message")] - [:div.sign-info - [:a.btn-primary.btn-small - {:on-click (fn [] (st/emit! #(dissoc % :exception)))} - (tr "labels.retry")]]]) + (let [new-css-system (mf/use-ctx ctx/new-css-system)] + (if new-css-system + [:> static-header {} + [:div {:class (stl/css :main-message)} (tr "labels.service-unavailable.main-message")] + [:div {:class (stl/css :desc-message)} (tr "labels.service-unavailable.desc-message")] + [:div {:class (stl/css :sign-info)} + [:button + {:on-click (fn [] (st/emit! (rt/assign-exception nil)))} + (tr "labels.retry")]]] + + [:> static-header {} + [:div.main-message (tr "labels.service-unavailable.main-message")] + [:div.desc-message (tr "labels.service-unavailable.desc-message")] + [:div.sign-info + [:a.btn-primary.btn-small + {:on-click (fn [] (st/emit! #(dissoc % :exception)))} + (tr "labels.retry")]]]))) (mf/defc internal-error [] - [:> static-header {} - [:div.image i/icon-empty] - [:div.main-message (tr "labels.internal-error.main-message")] - [:div.desc-message (tr "labels.internal-error.desc-message")] - [:div.sign-info - [:a.btn-primary.btn-small - {:on-click (fn [] (st/emit! (rt/assign-exception nil)))} - (tr "labels.retry")]]]) + (let [new-css-system (mf/use-ctx ctx/new-css-system)] + (if new-css-system + [:> static-header {} + [:div {:class (stl/css :main-message)} (tr "labels.internal-error.main-message")] + [:div {:class (stl/css :desc-message)} (tr "labels.internal-error.desc-message")] + [:div {:class (stl/css :sign-info)} + [:button + {:on-click (fn [] (st/emit! (rt/assign-exception nil)))} + (tr "labels.retry")]]] + + [:> static-header {} + [:div.image i/icon-empty] + [:div.main-message (tr "labels.internal-error.main-message")] + [:div.desc-message (tr "labels.internal-error.desc-message")] + [:div.sign-info + [:a.btn-primary.btn-small + {:on-click (fn [] (st/emit! (rt/assign-exception nil)))} + (tr "labels.retry")]]]))) (mf/defc exception-page [{:keys [data] :as props}] - (case (:type data) - :not-found - [:& not-found] + (let [new-css-system (features/use-feature "styles/v2")] + [:& (mf/provider ctx/new-css-system) {:value new-css-system} + (case (:type data) + :not-found + [:& not-found] - :bad-gateway - [:& bad-gateway] + :bad-gateway + [:& bad-gateway] - :service-unavailable - [:& service-unavailable] - - [:& internal-error])) + :service-unavailable + [:& service-unavailable] + [:& internal-error])])) diff --git a/frontend/src/app/main/ui/static.scss b/frontend/src/app/main/ui/static.scss new file mode 100644 index 0000000000..63e00828b5 --- /dev/null +++ b/frontend/src/app/main/ui/static.scss @@ -0,0 +1,91 @@ +// 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 *; + +.exception-layout { + width: 100%; + height: 100%; + background-color: $db-secondary; +} + +.deco-before, +.deco-after { + position: absolute; + left: calc(50% - $s-40); + + svg { + position: absolute; + fill: $df-secondary; + height: 1537px; + width: $s-80; + } +} + +.deco-before { + height: 34vh; + top: 0; + svg { + bottom: 0; + } +} + +.deco-after { + height: 34vh; + bottom: 0; + svg { + top: 0; + } +} + +.exception-header { + padding: $s-24 $s-32; + position: fixed; + svg { + fill: $df-primary; + width: $s-48; + height: auto; + } +} + +.exception-content { + display: flex; + height: 100%; + justify-content: center; + width: 100%; + + .container { + align-items: center; + display: flex; + flex-direction: column; + gap: $s-16; + height: 34vh; + justify-content: center; + margin-top: 33vh; + text-align: center; + width: $s-640; + } +} + +.main-message { + @include bigTitleTipography; + color: $df-primary; +} + +.desc-message { + @include bigTitleTipography; + color: $df-secondary; +} + +.sign-info { + text-align: center; + button { + @extend .button-primary; + text-transform: uppercase; + padding: $s-8 $s-16; + font-size: $fs-11; + } +} From a899d94619b965d86b95aff6ec01d8f21814a8e9 Mon Sep 17 00:00:00 2001 From: "alonso.torres" Date: Mon, 27 Nov 2023 22:59:20 +0100 Subject: [PATCH 6/6] :sparkles: Improvements after review --- .../main/ui/components/context_menu_a11y.cljs | 6 +- .../main/ui/components/context_menu_a11y.scss | 3 + .../src/app/main/ui/dashboard/comments.scss | 4 +- frontend/src/app/main/ui/dashboard/fonts.cljs | 30 +- frontend/src/app/main/ui/dashboard/fonts.scss | 6 + frontend/src/app/main/ui/dashboard/grid.cljs | 26 +- frontend/src/app/main/ui/dashboard/grid.scss | 2 +- .../src/app/main/ui/dashboard/projects.cljs | 35 +- .../src/app/main/ui/dashboard/sidebar.cljs | 312 +++++++++++------- .../src/app/main/ui/dashboard/sidebar.scss | 9 +- frontend/src/app/main/ui/dashboard/team.scss | 16 +- frontend/src/app/main/ui/settings.scss | 90 ++--- .../app/main/ui/settings/access_tokens.cljs | 15 +- .../src/app/main/ui/settings/profile.cljs | 16 +- .../src/app/main/ui/settings/profile.scss | 4 +- .../src/app/main/ui/settings/sidebar.scss | 2 +- frontend/src/app/main/ui/static.cljs | 39 +-- 17 files changed, 359 insertions(+), 256 deletions(-) diff --git a/frontend/src/app/main/ui/components/context_menu_a11y.cljs b/frontend/src/app/main/ui/components/context_menu_a11y.cljs index 21d5bf8082..1b8bc1c610 100644 --- a/frontend/src/app/main/ui/components/context_menu_a11y.cljs +++ b/frontend/src/app/main/ui/components/context_menu_a11y.cljs @@ -217,9 +217,9 @@ :tab-index "0" :on-key-down (fn [event] (dom/prevent-default event))} - [:div {:class (stl/css :context-menu-action :submenu-back) - :data-no-close true - :on-click exit-submenu} + [:button {:class (stl/css :context-menu-action :submenu-back) + :data-no-close true + :on-click exit-submenu} [:span {:class (stl/css :submenu-icon-back)} i/arrow-refactor] parent-option]] diff --git a/frontend/src/app/main/ui/components/context_menu_a11y.scss b/frontend/src/app/main/ui/components/context_menu_a11y.scss index f19a4d355b..bd4e89fabf 100644 --- a/frontend/src/app/main/ui/components/context_menu_a11y.scss +++ b/frontend/src/app/main/ui/components/context_menu_a11y.scss @@ -72,6 +72,9 @@ display: flex; align-items: center; font-weight: $fw700; + background: none; + border: none; + cursor: pointer; .submenu-icon-back svg { @extend .button-icon-small; stroke: var(--menu-foreground-color); diff --git a/frontend/src/app/main/ui/dashboard/comments.scss b/frontend/src/app/main/ui/dashboard/comments.scss index 9de57d692f..ed615fa73a 100644 --- a/frontend/src/app/main/ui/dashboard/comments.scss +++ b/frontend/src/app/main/ui/dashboard/comments.scss @@ -85,17 +85,17 @@ } .dropdown { + @include menuShadow; background-color: $db-tertiary; border-radius: $br-8; border: $s-1 solid transparent; bottom: $s-4; - box-shadow: 0px 2px 8px rgba(0, 0, 0, 0.25); height: 40vh; max-height: $s-480; min-height: $s-200; position: absolute; width: 100%; - z-index: 12; + z-index: $z-index-3; hr { margin: 0; diff --git a/frontend/src/app/main/ui/dashboard/fonts.cljs b/frontend/src/app/main/ui/dashboard/fonts.cljs index cedfdaf560..f81d194f5a 100644 --- a/frontend/src/app/main/ui/dashboard/fonts.cljs +++ b/frontend/src/app/main/ui/dashboard/fonts.cljs @@ -113,7 +113,13 @@ (fn [items] (run! on-delete items)) - problematic-fonts? (some :height-warning? (vals @fonts))] + problematic-fonts? (some :height-warning? (vals @fonts)) + + handle-upload-all + (mf/use-callback (mf/deps @fonts) #(on-upload-all (vals @fonts))) + + handle-dismiss-all + (mf/use-callback (mf/deps @fonts) #(on-dismiss-all (vals @fonts)))] (if new-css-system [:div {:class (stl/css :dashboard-fonts-upload)} @@ -144,20 +150,18 @@ [:div {:class (stl/css :icon)} i/msg-warning] [:div {:class (stl/css :content)} [:& i18n/tr-html {:tag-name "span" - :label "dashboard.fonts.warning-text"}]]])] - - ] + :label "dashboard.fonts.warning-text"}]]])]] [:* (when (some? (vals @fonts)) [:div {:class (stl/css :font-item :table-row)} [:span (tr "dashboard.fonts.fonts-added" (i18n/c (count (vals @fonts))))] [:div {:class (stl/css :table-field :options)} - [:div {:class (stl/css :btn-primary) - :on-click #(on-upload-all (vals @fonts)) :data-test "upload-all"} + [:button {:class (stl/css :btn-primary) + :on-click handle-upload-all :data-test "upload-all"} [:span (tr "dashboard.fonts.upload-all")]] - [:div {:class (stl/css :btn-secondary) - :on-click #(on-dismiss-all (vals @fonts)) :data-test "dismiss-all"} + [:button {:class (stl/css :btn-secondary) + :on-click handle-dismiss-all :data-test "dismiss-all"} [:span (tr "dashboard.fonts.dismiss-all")]]]]) (for [item (sort-by :font-family (vals @fonts))] @@ -340,19 +344,16 @@ :on-click #(on-delete-variant (:id item))} i/plus]])] - [:div] - (if @edit? [:div {:class (stl/css :table-field :options)} [:button - { - :disabled (str/blank? @state) + {:disabled (str/blank? @state) :on-click on-save :class (stl/css-case :btn-primary true :btn-disabled (str/blank? @state))} (tr "labels.save")] - [:span {:class (stl/css :icon :close) - :on-click on-cancel} i/close]] + [:button {:class (stl/css :icon :close) + :on-click on-cancel} i/close]] [:div {:class (stl/css :table-field :options)} [:span {:class (stl/css :icon) @@ -427,7 +428,6 @@ [:div {:class (stl/css :installed-fonts-header)} [:div {:class (stl/css :table-field :family)} (tr "labels.font-family")] [:div {:class (stl/css :table-field :variants)} (tr "labels.font-variants")] - [:div] [:div {:class (stl/css :table-field :search-input)} [:input {:placeholder (tr "labels.search-font") :default-value "" diff --git a/frontend/src/app/main/ui/dashboard/fonts.scss b/frontend/src/app/main/ui/dashboard/fonts.scss index 7265fa51cd..8741a6289f 100644 --- a/frontend/src/app/main/ui/dashboard/fonts.scss +++ b/frontend/src/app/main/ui/dashboard/fonts.scss @@ -14,6 +14,10 @@ padding-left: $s-120; overflow-y: auto; padding-bottom: $s-120; + + .btn-primary { + font-size: $fs-11; + } } .dashboard-installed-fonts { @@ -193,6 +197,8 @@ } &.close { + background: none; + border: none; svg { transform: rotate(45deg); fill: $df-secondary; diff --git a/frontend/src/app/main/ui/dashboard/grid.cljs b/frontend/src/app/main/ui/dashboard/grid.cljs index 2241a7239c..7775177894 100644 --- a/frontend/src/app/main/ui/dashboard/grid.cljs +++ b/frontend/src/app/main/ui/dashboard/grid.cljs @@ -431,7 +431,19 @@ (dom/stop-propagation event) (swap! local assoc :edition true - :menu-open false)))] + :menu-open false))) + + handle-key-down + (mf/use-callback + (mf/deps on-navigate on-select) + (fn [event] + (dom/stop-propagation event) + (when (kbd/enter? event) + (on-navigate event)) + (when (kbd/shift? event) + (when (or (kbd/down-arrow? event) (kbd/left-arrow? event) (kbd/up-arrow? event) (kbd/right-arrow? event)) + (on-select event)) ;; TODO Fix this + )))] (mf/with-effect [selected? local] (when (and (not selected?) (:menu-open @local)) @@ -441,19 +453,11 @@ [:li {:class (stl/css-case :grid-item true :project-th true :library library-view?)} [:button - {:tab-index "0" - :class (stl/css-case :selected selected? :library library-view?) + {:class (stl/css-case :selected selected? :library library-view?) :ref node-ref :draggable true :on-click on-select - :on-key-down (fn [event] - (dom/stop-propagation event) - (when (kbd/enter? event) - (on-navigate event)) - (when (kbd/shift? event) - (when (or (kbd/down-arrow? event) (kbd/left-arrow? event) (kbd/up-arrow? event) (kbd/right-arrow? event)) - (on-select event)) ;; TODO Fix this - )) + :on-key-down handle-key-down :on-double-click on-navigate :on-drag-start on-drag-start :on-context-menu on-menu-click} diff --git a/frontend/src/app/main/ui/dashboard/grid.scss b/frontend/src/app/main/ui/dashboard/grid.scss index 096ef69033..cd64a5cd76 100644 --- a/frontend/src/app/main/ui/dashboard/grid.scss +++ b/frontend/src/app/main/ui/dashboard/grid.scss @@ -170,7 +170,7 @@ width: $s-32; height: $s-32; background-color: $da-tertiary; - border-radius: 50%; + border-radius: $br-circle; color: $db-secondary; font-size: $fs-16; display: flex; diff --git a/frontend/src/app/main/ui/dashboard/projects.cljs b/frontend/src/app/main/ui/dashboard/projects.cljs index f84f160063..9213bebb72 100644 --- a/frontend/src/app/main/ui/dashboard/projects.cljs +++ b/frontend/src/app/main/ui/dashboard/projects.cljs @@ -257,9 +257,9 @@ toggle-pin (mf/use-fn (mf/deps project) - (fn [event] - (dom/stop-propagation event) - (st/emit! (dd/toggle-project-pin project)))) + (fn [event] + (dom/stop-propagation event) + (st/emit! (dd/toggle-project-pin project)))) on-menu-click (mf/use-fn @@ -324,7 +324,23 @@ (st/emit! (dd/fetch-files {:project-id project-id}) (dd/fetch-recent-files (:id team)) (dd/fetch-projects (:id team)) - (dd/clear-selected-files))))] + (dd/clear-selected-files)))) + + handle-create-click + (mf/use-callback + (mf/deps on-create-click) + (fn [event] + (when (kbd/enter? event) + (on-create-click event)))) + + + handle-menu-click + (mf/use-callback + (mf/deps on-menu-click) + (fn [event] + (when (kbd/enter? event) + (dom/stop-propagation event) + (on-menu-click event))))] (if new-css-system [:article {:class (stl/css-case :dashboard-project-row true :first first?)} @@ -375,10 +391,7 @@ :alt (tr "dashboard.new-file") :aria-label (tr "dashboard.new-file") :data-test "project-new-file" - :tab-index "0" - :on-key-down (fn [event] - (when (kbd/enter? event) - (on-create-click event)))} + :on-key-down handle-create-click} i/close] [:button @@ -387,11 +400,7 @@ :alt (tr "dashboard.options") :aria-label (tr "dashboard.options") :data-test "project-options" - :tab-index "0" - :on-key-down (fn [event] - (when (kbd/enter? event) - (dom/stop-propagation event) - (on-menu-click event)))} + :on-key-down handle-menu-click} i/actions]]]] [:& line-grid diff --git a/frontend/src/app/main/ui/dashboard/sidebar.cljs b/frontend/src/app/main/ui/dashboard/sidebar.cljs index 1994630986..7a2c3a50e5 100644 --- a/frontend/src/app/main/ui/dashboard/sidebar.cljs +++ b/frontend/src/app/main/ui/dashboard/sidebar.cljs @@ -47,12 +47,13 @@ selected-project (:selected-project dstate) edit-id (:project-for-edit dstate) - local (mf/use-state + local* (mf/use-state {:menu-open false :menu-pos nil :edition? (= (:id item) edit-id) :dragging? false}) + local @local* on-click (mf/use-callback (mf/deps item) @@ -78,15 +79,15 @@ (fn [event] (let [position (dom/get-client-position event)] (dom/prevent-default event) - (swap! local assoc + (swap! local* assoc :menu-open true :menu-pos position)))) on-menu-close - (mf/use-callback #(swap! local assoc :menu-open false)) + (mf/use-callback #(swap! local* assoc :menu-open false)) on-edit-open - (mf/use-callback #(swap! local assoc :edition? true)) + (mf/use-callback #(swap! local* assoc :edition? true)) on-edit (mf/use-callback @@ -94,7 +95,7 @@ (fn [name] (st/emit! (-> (dd/rename-project (assoc item :name name)) (with-meta {::ev/origin "dashboard:sidebar"}))) - (swap! local assoc :edition? false))) + (swap! local* assoc :edition? false))) on-drag-enter (mf/use-callback @@ -104,7 +105,7 @@ (dom/prevent-default e) (when-not (dnd/from-child? e) (when (not= selected-project (:id item)) - (swap! local assoc :dragging? true)))))) + (swap! local* assoc :dragging? true)))))) on-drag-over (mf/use-callback @@ -116,7 +117,7 @@ (mf/use-callback (fn [e] (when-not (dnd/from-child? e) - (swap! local assoc :dragging? false)))) + (swap! local* assoc :dragging? false)))) on-drop-success (mf/use-callback @@ -128,7 +129,7 @@ (mf/use-callback (mf/deps item selected-files) (fn [_] - (swap! local assoc :dragging? false) + (swap! local* assoc :dragging? false) (when (not= selected-project (:id item)) (let [data {:ids selected-files :project-id (:id item)} @@ -139,7 +140,7 @@ [:* [:li {:tab-index "0" :class (if selected? (stl/css :current) - (when (:dragging? @local) (stl/css :dragging))) + (when (:dragging? local) (stl/css :dragging))) :on-click on-click :on-key-down on-key-down :on-double-click on-edit-open @@ -148,14 +149,14 @@ :on-drag-over on-drag-over :on-drag-leave on-drag-leave :on-drop on-drop} - (if (:edition? @local) + (if (:edition? local) [:& inline-edition {:content (:name item) :on-end on-edit}] [:span {:class (stl/css :element-title)} (:name item)])] [:& project-menu {:project item - :show? (:menu-open @local) - :left (:x (:menu-pos @local)) - :top (:y (:menu-pos @local)) + :show? (:menu-open local) + :left (:x (:menu-pos local)) + :top (:y (:menu-pos local)) :on-edit on-edit-open :on-menu-close on-menu-close}]] @@ -163,7 +164,7 @@ [:* [:li {:tab-index "0" :class (if selected? "current" - (when (:dragging? @local) "dragging")) + (when (:dragging? local) "dragging")) :on-click on-click :on-key-down on-key-down :on-double-click on-edit-open @@ -172,14 +173,14 @@ :on-drag-over on-drag-over :on-drag-leave on-drag-leave :on-drop on-drop} - (if (:edition? @local) + (if (:edition? local) [:& inline-edition {:content (:name item) :on-end on-edit}] [:span.element-title (:name item)])] [:& project-menu {:project item - :show? (:menu-open @local) - :left (:x (:menu-pos @local)) - :top (:y (:menu-pos @local)) + :show? (:menu-open local) + :left (:x (:menu-pos local)) + :top (:y (:menu-pos local)) :on-edit on-edit-open :on-menu-close on-menu-close}]]))) @@ -225,7 +226,14 @@ (dom/focus! search-title) (dom/set-attribute! search-title "tabindex" "-1"))))) (dom/prevent-default e) - (dom/stop-propagation e))))] + (dom/stop-propagation e)))) + + handle-clear-search + (mf/use-callback + (mf/deps on-clear-click) + (fn [event] + (when (kbd/enter? event) + (on-clear-click event))))] (if new-css-system [:form {:class (stl/css :sidebar-search)} @@ -249,9 +257,7 @@ {:class (stl/css :clear-search) :tab-index "0" :on-click on-clear-click - :on-key-down (fn [event] - (when (kbd/enter? event) - (on-clear-click event)))} + :on-key-down handle-clear-search} i/close] [:div @@ -299,14 +305,22 @@ team-selected (mf/use-callback (fn [team-id] - (st/emit! (dd/go-to-projects team-id))))] + (st/emit! (dd/go-to-projects team-id)))) + + handle-select-default + (fn [event] + (when (kbd/enter? event) + (team-selected (:default-team-id profile) event))) + + handle-select-team + (fn [id event] + (when (kbd/enter? event) + (team-selected id event)))] (if new-css-system [:* [:> dropdown-menu-item* {:on-click (partial team-selected (:default-team-id profile)) - :on-key-down (fn [event] - (when (kbd/enter? event) - (team-selected (:default-team-id profile) event))) + :on-key-down handle-select-default :id "teams-selector-default-team" :class (stl/css :team-name)} [:span {:class (stl/css :team-icon)} i/logo-icon] @@ -316,9 +330,7 @@ (for [team-item (remove :is-default (vals teams))] [:> dropdown-menu-item* {:on-click (partial team-selected (:id team-item)) - :on-key-down (fn [event] - (when (kbd/enter? event) - (team-selected (:id team-item) event))) + :on-key-down (partial handle-select-team (:id team-item)) :id (str "teams-selector-" (:id team-item)) :class (stl/css :team-name) :key (str "teams-selector-" (:id team-item))} @@ -560,7 +572,47 @@ "teams-options-rename") "teams-options-leave-team" (when (get-in team [:permissions :is-owner]) - "teams-options-delete-team")]] + "teams-options-delete-team")] + + handle-show-team-click + (fn [event] + (dom/stop-propagation event) + (swap! show-teams-ddwn? not) + (reset! show-team-opts-ddwn? false)) + + handle-show-team-keydown + (fn [event] + (when (or (kbd/space? event) (kbd/enter? event)) + (dom/prevent-default event) + (reset! show-teams-ddwn? true) + (reset! show-team-opts-ddwn? false) + (ts/schedule-on-idle + (fn [] + (let [first-element (dom/get-element (first ids))] + (when first-element + (dom/focus! first-element))))))) + + handle-show-opts-click + (fn [event] + (dom/stop-propagation event) + (swap! show-team-opts-ddwn? not) + (reset! show-teams-ddwn? false)) + + handle-show-opts-keydown + (fn [event] + (when (or (kbd/space? event) (kbd/enter? event)) + (dom/prevent-default event) + (reset! show-team-opts-ddwn? true) + (reset! show-teams-ddwn? false) + (ts/schedule-on-idle + (fn [] + (let [first-element (dom/get-element (first options-ids))] + (when first-element + (dom/focus! first-element))))))) + + handle-close-team + (fn [] + (reset! show-teams-ddwn? false))] (if new-css-system [:div {:class (stl/css :sidebar-team-switch)} @@ -568,21 +620,9 @@ [:button {:class (stl/css :current-team) :tab-index "0" - :on-click - (fn [event] - (dom/stop-propagation event) - (reset! show-teams-ddwn? true)) + :on-click handle-show-team-click + :on-key-down handle-show-team-keydown} - :on-key-down - (fn [event] - (when (or (kbd/space? event) (kbd/enter? event)) - (dom/prevent-default event) - (reset! show-teams-ddwn? true) - (ts/schedule-on-idle - (fn [] - (let [first-element (dom/get-element (first ids))] - (when first-element - (dom/focus! first-element)))))))} (if (:is-default team) [:div {:class (stl/css :team-name)} @@ -599,24 +639,14 @@ (when-not (:is-default team) [:button {:class (stl/css :switch-options) - :on-click (fn [event] - (dom/stop-propagation event) - (reset! show-team-opts-ddwn? true)) + :on-click handle-show-opts-click :tab-index "0" - :on-key-down (fn [event] - (when (or (kbd/space? event) (kbd/enter? event)) - (dom/prevent-default event) - (reset! show-team-opts-ddwn? true) - (ts/schedule-on-idle - (fn [] - (let [first-element (dom/get-element (first options-ids))] - (when first-element - (dom/focus! first-element)))))))} + :on-key-down handle-show-opts-keydown} i/actions])] ;; Teams Dropdown [:& dropdown-menu {:show @show-teams-ddwn? - :on-close #(reset! show-teams-ddwn? false) + :on-close handle-close-team :ids ids :list-class (stl/css :dropdown :teams-dropdown)} [:& teams-selector-dropdown-items {:ids ids @@ -922,7 +952,77 @@ handle-show-comments (mf/use-callback (fn [] - (reset! show-comments* true)))] + (reset! show-comments* true))) + + handle-click + (mf/use-callback + (fn [event] + (dom/stop-propagation event) + (swap! show not))) + + handle-key-down + (mf/use-callback + (fn [event] + (when (kbd/enter? event) + (reset! show true)))) + + handle-close + (fn [event] + (dom/stop-propagation event) + (reset! show false)) + + handle-key-down-profile + (mf/use-callback + (mf/deps on-click) + (fn [event] + (when (kbd/enter? event) + (on-click :settings-profile event)))) + + handle-click-url + (mf/use-callback + (fn [event] + (let [url (-> (dom/get-current-target event) + (dom/get-data "url"))] + (dom/open-new-window url)))) + + handle-keydown-url + (mf/use-callback + (fn [event] + (let [url (-> (dom/get-current-target event) + (dom/get-data "url"))] + (when (kbd/enter? event) + (dom/open-new-window url))))) + + handle-show-release-notes + (mf/use-callback + (mf/deps show-release-notes) + (fn [event] + (when (kbd/enter? event) + (show-release-notes)))) + + handle-feedback-click + (mf/use-callback + (mf/deps on-click) + #(on-click :settings-feedback %)) + + handle-feedback-keydown + (mf/use-callback + (mf/deps on-click) + (fn [event] + (when (kbd/enter? event) + (on-click :settings-feedback event)))) + + handle-logout-click + (mf/use-callback + (mf/deps on-click) + #(on-click (du/logout) %)) + + handle-logout-keydown + (mf/use-callback + (mf/deps on-click) + (fn [event] + (when (kbd/enter? event) + (on-click (du/logout) event))))] (if new-css-system [:* (when (and team profile) @@ -936,99 +1036,78 @@ [:div {:class (stl/css :profile-section)} [:div {:class (stl/css :profile) :tab-index "0" - :on-click (fn [event] - (dom/stop-propagation event) - (reset! show true)) - :on-key-down (fn [event] - (when (kbd/enter? event) - (reset! show true))) + :on-click handle-click + :on-key-down handle-key-down :data-test "profile-btn"} [:img {:src photo :alt (:fullname profile)}] [:span (:fullname profile)]] - [:& dropdown-menu {:on-close (fn [event] - (dom/stop-propagation event) - (reset! show false)) - :show @show} + [:& dropdown-menu {:on-close handle-close :show @show} [:ul {:class (stl/css :dropdown)} - [:li {:tab-index (if show "0" "-1") + [:li {:tab-index (if @show "0" "-1") :on-click (partial on-click :settings-profile) - :on-key-down (fn [event] - (when (kbd/enter? event) - (on-click :settings-profile event))) + :on-key-down handle-key-down-profile :data-test "profile-profile-opt"} [:span {:class (stl/css :text)} (tr "labels.your-account")]] [:li {:class (stl/css :separator) - :tab-index (if show "0" "-1") - :on-click #(dom/open-new-window "https://help.penpot.app") - :on-key-down (fn [event] - (when (kbd/enter? event) - (dom/open-new-window "https://help.penpot.app"))) + :tab-index (if @show "0" "-1") + :data-url "https://help.penpot.app" + :on-click handle-click-url + :on-key-down handle-keydown-url :data-test "help-center-profile-opt"} [:span {:class (stl/css :text)} (tr "labels.help-center")]] - [:li {:tab-index (if show "0" "-1") - :on-click #(dom/open-new-window "https://community.penpot.app") - :on-key-down (fn [event] - (when (kbd/enter? event) - (dom/open-new-window "https://community.penpot.app")))} + [:li {:tab-index (if @show "0" "-1") + :data-url "https://community.penpot.app" + :on-click handle-click-url + :on-key-down handle-keydown-url} [:span {:class (stl/css :text)} (tr "labels.community")]] - [:li {:tab-index (if show "0" "-1") - :on-click #(dom/open-new-window "https://www.youtube.com/c/Penpot") - :on-key-down (fn [event] - (when (kbd/enter? event) - (dom/open-new-window "https://www.youtube.com/c/Penpot")))} + [:li {:tab-index (if @show "0" "-1") + :data-url "https://www.youtube.com/c/Penpot" + :on-click handle-click-url + :on-key-down handle-keydown-url} [:span {:class (stl/css :text)} (tr "labels.tutorials")]] - [:li {:tab-index (if show "0" "-1") + [:li {:tab-index (if @show "0" "-1") :on-click show-release-notes - :on-key-down (fn [event] - (when (kbd/enter? event) - (show-release-notes)))} + :on-key-down handle-show-release-notes} [:span {:class (stl/css :text)} (tr "labels.release-notes")]] [:li {:class (stl/css :separator) - :tab-index (if show "0" "-1") - :on-click #(dom/open-new-window "https://penpot.app/libraries-templates") - :on-key-down (fn [event] - (when (kbd/enter? event) - (dom/open-new-window "https://penpot.app/libraries-templates"))) + :tab-index (if @show "0" "-1") + :data-url "https://penpot.app/libraries-templates" + :on-click handle-click-url + :on-key-down handle-keydown-url :data-test "libraries-templates-profile-opt"} [:span {:class (stl/css :text)} (tr "labels.libraries-and-templates")]] - [:li {:tab-index (if show "0" "-1") - :on-click #(dom/open-new-window "https://github.com/penpot/penpot") - :on-key-down (fn [event] - (when (kbd/enter? event) - (dom/open-new-window "https://github.com/penpot/penpot")))} + [:li {:tab-index (if @show "0" "-1") + :data-url "https://github.com/penpot/penpot" + :on-click handle-click-url + :on-key-down handle-keydown-url} [:span {:class (stl/css :text)} (tr "labels.github-repo")]] - [:li {:tab-index (if show "0" "-1") - :on-click #(dom/open-new-window "https://penpot.app/terms") - :on-key-down (fn [event] - (when (kbd/enter? event) - (dom/open-new-window "https://penpot.app/terms")))} + [:li {:tab-index (if @show "0" "-1") + :data-url "https://penpot.app/terms" + :on-click handle-click-url + :on-key-down handle-keydown-url} [:span {:class (stl/css :text)} (tr "auth.terms-of-service")]] (when (contains? cf/flags :user-feedback) [:li {:class (stl/css :separator) - :tab-index (if show "0" "-1") - :on-click (partial on-click :settings-feedback) - :on-key-down (fn [event] - (when (kbd/enter? event) - (on-click :settings-feedback event))) + :tab-index (if @show "0" "-1") + :on-click handle-feedback-click + :on-key-down handle-feedback-keydown :data-test "feedback-profile-opt"} [:span {:class (stl/css :text)} (tr "labels.give-feedback")]]) [:li {:class (stl/css :separator) - :tab-index (if show "0" "-1") - :on-click #(on-click (du/logout) %) - :on-key-down (fn [event] - (when (kbd/enter? event) - (on-click (du/logout) event))) + :tab-index (if @show "0" "-1") + :on-click handle-logout-click + :on-key-down handle-logout-keydown :data-test "logout-profile-opt"} [:span {:class (stl/css :icon)} i/exit] [:span {:class (stl/css :text)} (tr "labels.logout")]]]] @@ -1176,4 +1255,3 @@ [:& profile-section {:profile profile :team team}]]))) - diff --git a/frontend/src/app/main/ui/dashboard/sidebar.scss b/frontend/src/app/main/ui/dashboard/sidebar.scss index 0d745a0799..0dec1777b5 100644 --- a/frontend/src/app/main/ui/dashboard/sidebar.scss +++ b/frontend/src/app/main/ui/dashboard/sidebar.scss @@ -16,7 +16,7 @@ margin: 0 $s-16 0 0; padding: $s-16 0 0 0; - z-index: 1; + z-index: $z-index-1; display: flex; flex-direction: column; height: 100%; @@ -123,6 +123,7 @@ cursor: pointer; background-color: transparent; border: none; + height: 100%; svg { fill: $df-secondary; @@ -140,12 +141,12 @@ } .dropdown { + @include menuShadow; position: absolute; - z-index: 12; + z-index: $z-index-4; background-color: $db-tertiary; border: $s-1 solid $db-cuaternary; border-radius: $br-8; - box-shadow: 0px 2px 8px rgba(0, 0, 0, 0.25); .separator { border-color: transparent; @@ -199,7 +200,7 @@ left: 0; top: $s-52; - z-index: 12; + max-height: $s-480; overflow-x: hidden; overflow-y: auto; diff --git a/frontend/src/app/main/ui/dashboard/team.scss b/frontend/src/app/main/ui/dashboard/team.scss index b8e3882a86..18ec4eadd4 100644 --- a/frontend/src/app/main/ui/dashboard/team.scss +++ b/frontend/src/app/main/ui/dashboard/team.scss @@ -102,16 +102,8 @@ } } .btn-primary { - flex-shrink: 0; - width: 100%; - font-size: $fs-12; - text-transform: uppercase; - background-color: $db-tertiary; - color: $df-primary; - &:hover { - color: $da-primary; - background-color: $db-cuaternary; - } + @extends .button-primary; + height: $s-32; } } @@ -127,7 +119,7 @@ position: absolute; top: $s-32; width: $s-152; - z-index: 12; + z-index: $z-index-4; hr { margin: 0; @@ -511,7 +503,7 @@ align-items: center; border-radius: 50%; color: $df-primary; - z-index: 14; + z-index: $z-index-modal; background-color: $da-primary; height: $s-120; diff --git a/frontend/src/app/main/ui/settings.scss b/frontend/src/app/main/ui/settings.scss index e295be303b..2fc327282a 100644 --- a/frontend/src/app/main/ui/settings.scss +++ b/frontend/src/app/main/ui/settings.scss @@ -10,8 +10,8 @@ .dashboard { background-color: $db-primary; display: grid; - grid-template-rows: 50px 1fr; - grid-template-columns: 40px 256px 1fr; + grid-template-rows: $s-48 1fr; + grid-template-columns: $s-40 $s-256 1fr; height: 100vh; } @@ -20,7 +20,7 @@ flex-direction: column; position: relative; grid-row: 1 / span 2; - padding: 1rem 1rem 0 0; + padding: $s-16 $s-16 0 0; } .dashboard-container { @@ -54,24 +54,24 @@ } .form-container { - width: 800px; - margin: 50px auto 2rem 120px; + width: $s-800; + margin: $s-48 auto $s-32 $s-120; display: flex; - max-width: 368px; + max-width: $s-368; width: 100%; &.two-columns { - max-width: 536px; + max-width: $s-520; justify-content: space-between; flex-direction: row; } h2 { - margin-bottom: 1rem; + margin-bottom: $s-16; } form { - width: 468px; + width: $s-468; .custom-input, .custom-select { @@ -80,26 +80,26 @@ position: relative; text-transform: uppercase; color: $df-primary; - font-size: 11px; - margin-bottom: 12px; - margin-left: -4px; + font-size: $fs-11; + margin-bottom: $s-12; + margin-left: calc(-1 * $s-4); } input, select { background-color: $db-tertiary; - border-radius: 8px; + border-radius: $s-8; border-color: transparent; color: $df-primary; - padding: 0 15px; + padding: 0 $s-16; &:focus { - outline: 1px solid $da-primary; + outline: $s-1 solid $da-primary; } ::placeholder { color: $df-secondary; } } .help-icon { - bottom: 12px; + bottom: $s-12; top: auto; svg { fill: $df-secondary; @@ -114,30 +114,30 @@ } .input-container { background-color: $db-tertiary; - border-radius: 8px; + border-radius: $s-8; border-color: transparent; - margin-top: 22px; + margin-top: $s-24; .main-content { label { position: absolute; - top: -24px; + top: calc(-1 * $s-24); } span { color: $df-primary; } } &:focus { - border: 1px solid $da-primary; + border: $s-1 solid $da-primary; } } textarea { - border-radius: 8px; - padding: 12px 14px; + border-radius: $s-8; + padding: $s-12 $s-16; background-color: $db-tertiary; color: $df-primary; border: none; &:focus { - outline: 1px solid $da-primary; + outline: $s-1 solid $da-primary; } } } @@ -146,7 +146,7 @@ color: $df-primary; } .field-title:not(:first-child) { - margin-top: 64px; + margin-top: $s-64; } .field-text { @@ -155,7 +155,7 @@ button, .btn-secondary { width: 100%; - font-size: 11px; + font-size: $fs-11; text-transform: uppercase; background-color: $db-tertiary; color: $df-primary; @@ -169,21 +169,21 @@ } } .links { - margin-top: 12px; + margin-top: $s-12; } } .profile-form { display: flex; flex-direction: column; - max-width: 368px; + max-width: $s-368; width: 100%; .newsletter-subs { - border-bottom: 1px solid $df-secondary; - border-top: 1px solid $df-secondary; - padding: 30px 0; - margin-bottom: 31px; + border-bottom: $s-1 solid $df-secondary; + border-top: $s-1 solid $df-secondary; + padding: $s-32 0; + margin-bottom: $s-32; .newsletter-title { font-family: "worksans", sans-serif; @@ -195,15 +195,15 @@ font-family: "worksans", sans-serif; color: $db-primary; font-size: $fs-12; - margin-right: -17px; - margin-bottom: 13px; + margin-right: calc(-1 * $s-16); + margin-bottom: $s-12; } .info { font-family: "worksans", sans-serif; color: $df-secondary; font-size: $fs-12; - margin-bottom: 8px; + margin-bottom: $s-8; } .input-checkbox label { @@ -215,28 +215,28 @@ .avatar-form { display: flex; flex-direction: column; - width: 120px; - min-width: 120px; + width: $s-120; + min-width: $s-120; img { border-radius: 50%; flex-shrink: 0; - height: 120px; + height: $s-120; margin-right: $s-16; - width: 120px; + width: $s-120; } .image-change-field { position: relative; - width: 120px; - height: 120px; + width: $s-120; + height: $s-120; .update-overlay { opacity: 0; cursor: pointer; position: absolute; - width: 121px; - height: 121px; + width: $s-120; + height: $s-120; border-radius: 50%; font-size: $fs-24; color: $df-primary; @@ -247,8 +247,8 @@ } input[type="file"] { - width: 120px; - height: 120px; + width: $s-120; + height: $s-120; position: absolute; opacity: 0; cursor: pointer; @@ -268,6 +268,6 @@ .password-form { h2 { font-size: $fs-14; - margin-bottom: 20px; + margin-bottom: $s-20; } } diff --git a/frontend/src/app/main/ui/settings/access_tokens.cljs b/frontend/src/app/main/ui/settings/access_tokens.cljs index 6d5a0bafd3..de1ec0a7cc 100644 --- a/frontend/src/app/main/ui/settings/access_tokens.cljs +++ b/frontend/src/app/main/ui/settings/access_tokens.cljs @@ -291,7 +291,15 @@ (mf/use-fn (fn [event] (dom/prevent-default event) - (swap! local assoc :menu-open true)))] + (swap! local assoc :menu-open true))) + + on-keydown + (mf/use-callback + (mf/deps on-menu-click) + (fn [event] + (when (kbd/enter? event) + (dom/stop-propagation event) + (on-menu-click event))))] (if new-css-system [:div @@ -299,10 +307,7 @@ :tab-index "0" :ref menu-ref :on-click on-menu-click - :on-key-down (fn [event] - (when (kbd/enter? event) - (dom/stop-propagation event) - (on-menu-click event)))} + :on-key-down on-keydown} i/actions [:& context-menu-a11y {:on-close on-menu-close diff --git a/frontend/src/app/main/ui/settings/profile.cljs b/frontend/src/app/main/ui/settings/profile.cljs index 8dfb6b87b9..a6bb4ad308 100644 --- a/frontend/src/app/main/ui/settings/profile.cljs +++ b/frontend/src/app/main/ui/settings/profile.cljs @@ -49,7 +49,15 @@ form (fm/use-form :spec ::profile-form :initial profile :validators [(fm/validate-length :fullname fm/max-length-allowed (tr "auth.name.too-long")) - (fm/validate-not-empty :fullname (tr "auth.name.not-all-space"))])] + (fm/validate-not-empty :fullname (tr "auth.name.not-all-space"))]) + + handle-show-change-email + (mf/use-callback + #(modal/show! :change-email {})) + + handle-show-delete-account + (mf/use-callback + #(modal/show! :delete-account {}))] (if new-css-system [:& fm/form {:on-submit on-submit @@ -62,7 +70,7 @@ :label (tr "dashboard.your-name")}]] [:div {:class (stl/css :fields-row) - :on-click #(modal/show! :change-email {})} + :on-click handle-show-change-email} [:& fm/input {:type "email" :name :email @@ -72,7 +80,7 @@ [:div {:class (stl/css :options)} [:div.change-email - [:a {:on-click #(modal/show! :change-email {})} + [:a {:on-click handle-show-change-email} (tr "dashboard.change-email")]]]] [:> fm/submit-button* @@ -82,7 +90,7 @@ [:div {:class (stl/css :links)} [:div {:class (stl/css :link-item)} - [:a {:on-click #(modal/show! :delete-account {}) + [:a {:on-click handle-show-delete-account :data-test "remove-acount-btn"} (tr "dashboard.remove-account")]]]] diff --git a/frontend/src/app/main/ui/settings/profile.scss b/frontend/src/app/main/ui/settings/profile.scss index dc13b02310..c1f1b622b0 100644 --- a/frontend/src/app/main/ui/settings/profile.scss +++ b/frontend/src/app/main/ui/settings/profile.scss @@ -266,7 +266,7 @@ form.avatar-form { line-height: 6; text-align: center; background: $da-tertiary; - z-index: 14; + z-index: $z-index-modal; } input[type="file"] { @@ -276,7 +276,7 @@ form.avatar-form { opacity: 0; cursor: pointer; top: 0; - z-index: 15; + z-index: $z-index-modal; } &:hover { diff --git a/frontend/src/app/main/ui/settings/sidebar.scss b/frontend/src/app/main/ui/settings/sidebar.scss index 263ff24af2..e5e05cef46 100644 --- a/frontend/src/app/main/ui/settings/sidebar.scss +++ b/frontend/src/app/main/ui/settings/sidebar.scss @@ -16,7 +16,7 @@ height: 100%; margin: 0 $s-16 0 0; padding: $s-16 0 0 0; - z-index: 1; + z-index: $z-index-1; } .sidebar-content { diff --git a/frontend/src/app/main/ui/static.cljs b/frontend/src/app/main/ui/static.cljs index a9fa000c16..163b806710 100644 --- a/frontend/src/app/main/ui/static.cljs +++ b/frontend/src/app/main/ui/static.cljs @@ -57,65 +57,62 @@ (mf/defc bad-gateway [] - (let [new-css-system (mf/use-ctx ctx/new-css-system)] + (let [new-css-system (mf/use-ctx ctx/new-css-system) + handle-retry + (mf/use-callback + (fn [] (st/emit! (rt/assign-exception nil))))] (if new-css-system [:> static-header {} [:div {:class (stl/css :main-message)} (tr "labels.bad-gateway.main-message")] [:div {:class (stl/css :desc-message)} (tr "labels.bad-gateway.desc-message")] [:div {:class (stl/css :sign-info)} - [:button - {:on-click (fn [] (st/emit! (rt/assign-exception nil)))} - (tr "labels.retry")]]] + [:button {:on-click handle-retry} (tr "labels.retry")]]] [:> static-header {} [:div.image i/icon-empty] [:div.main-message (tr "labels.bad-gateway.main-message")] [:div.desc-message (tr "labels.bad-gateway.desc-message")] [:div.sign-info - [:a.btn-primary.btn-small - {:on-click (fn [] (st/emit! #(dissoc % :exception)))} - (tr "labels.retry")]]]))) + [:a.btn-primary.btn-small {:on-click handle-retry} (tr "labels.retry")]]]))) (mf/defc service-unavailable [] - (let [new-css-system (mf/use-ctx ctx/new-css-system)] + (let [new-css-system (mf/use-ctx ctx/new-css-system) + handle-retry + (mf/use-callback + (fn [] (st/emit! (rt/assign-exception nil))))] (if new-css-system [:> static-header {} [:div {:class (stl/css :main-message)} (tr "labels.service-unavailable.main-message")] [:div {:class (stl/css :desc-message)} (tr "labels.service-unavailable.desc-message")] [:div {:class (stl/css :sign-info)} - [:button - {:on-click (fn [] (st/emit! (rt/assign-exception nil)))} - (tr "labels.retry")]]] + [:button {:on-click handle-retry} (tr "labels.retry")]]] [:> static-header {} [:div.main-message (tr "labels.service-unavailable.main-message")] [:div.desc-message (tr "labels.service-unavailable.desc-message")] [:div.sign-info - [:a.btn-primary.btn-small - {:on-click (fn [] (st/emit! #(dissoc % :exception)))} - (tr "labels.retry")]]]))) + [:a.btn-primary.btn-small {:on-click handle-retry} (tr "labels.retry")]]]))) (mf/defc internal-error [] - (let [new-css-system (mf/use-ctx ctx/new-css-system)] + (let [new-css-system (mf/use-ctx ctx/new-css-system) + handle-retry + (mf/use-callback + (fn [] (st/emit! (rt/assign-exception nil))))] (if new-css-system [:> static-header {} [:div {:class (stl/css :main-message)} (tr "labels.internal-error.main-message")] [:div {:class (stl/css :desc-message)} (tr "labels.internal-error.desc-message")] [:div {:class (stl/css :sign-info)} - [:button - {:on-click (fn [] (st/emit! (rt/assign-exception nil)))} - (tr "labels.retry")]]] + [:button {:on-click handle-retry} (tr "labels.retry")]]] [:> static-header {} [:div.image i/icon-empty] [:div.main-message (tr "labels.internal-error.main-message")] [:div.desc-message (tr "labels.internal-error.desc-message")] [:div.sign-info - [:a.btn-primary.btn-small - {:on-click (fn [] (st/emit! (rt/assign-exception nil)))} - (tr "labels.retry")]]]))) + [:a.btn-primary.btn-small {:on-click handle-retry} (tr "labels.retry")]]]))) (mf/defc exception-page [{:keys [data] :as props}]