From e700f937db49206c3b8e6c258619d406011838cf Mon Sep 17 00:00:00 2001 From: "alonso.torres" Date: Fri, 13 Mar 2020 13:12:02 +0100 Subject: [PATCH] :japanese_ogre: layout for library --- .../styles/common/dependencies/colors.scss | 2 + frontend/resources/styles/main.scss | 2 + .../styles/main/layouts/library-page.scss | 273 ++++++++++++++++++ .../styles/main/partials/context-menu.scss | 34 +++ .../styles/main/partials/library-bar.scss | 1 + frontend/src/uxbox/builtins/icons.cljs | 1 + frontend/src/uxbox/main/ui.cljs | 3 +- frontend/src/uxbox/main/ui/dashboard.cljs | 6 +- .../ui/dashboard/components/context_menu.cljs | 15 + .../src/uxbox/main/ui/dashboard/elements.cljs | 2 +- .../src/uxbox/main/ui/dashboard/header.cljs | 26 -- .../src/uxbox/main/ui/dashboard/library.cljs | 136 +++++++++ .../uxbox/main/ui/dashboard/recent_files.cljs | 25 +- .../src/uxbox/main/ui/dashboard/sidebar.cljs | 5 +- 14 files changed, 492 insertions(+), 39 deletions(-) create mode 100644 frontend/resources/styles/main/layouts/library-page.scss create mode 100644 frontend/resources/styles/main/partials/context-menu.scss create mode 100644 frontend/src/uxbox/main/ui/dashboard/components/context_menu.cljs delete mode 100644 frontend/src/uxbox/main/ui/dashboard/header.cljs create mode 100644 frontend/src/uxbox/main/ui/dashboard/library.cljs diff --git a/frontend/resources/styles/common/dependencies/colors.scss b/frontend/resources/styles/common/dependencies/colors.scss index b896180efa..8c92847b78 100644 --- a/frontend/resources/styles/common/dependencies/colors.scss +++ b/frontend/resources/styles/common/dependencies/colors.scss @@ -26,10 +26,12 @@ $mix-percentage-dark: 81%; $mix-percentage-darker: 60%; $mix-percentage-light: 80%; $mix-percentage-lighter: 20%; +$mix-percentage-lightest: 10%; // Gray scale $color-gray-light: mix($color-gray, $color-white, $mix-percentage-light); $color-gray-lighter: mix($color-gray, $color-white, $mix-percentage-lighter); +$color-gray-lightest: mix($color-gray, $color-white, $mix-percentage-lightest); $color-gray-dark: mix($color-gray, $color-black, $mix-percentage-dark); $color-gray-darker: mix($color-gray, $color-black, $mix-percentage-darker); $color-gray-10: #E3E3E3; diff --git a/frontend/resources/styles/main.scss b/frontend/resources/styles/main.scss index 1106d6b6b4..dd77f3c8a2 100644 --- a/frontend/resources/styles/main.scss +++ b/frontend/resources/styles/main.scss @@ -29,6 +29,7 @@ @import 'main/layouts/login'; @import 'main/layouts/projects-page'; @import 'main/layouts/recent-files-page'; +@import 'main/layouts/library-page'; //################################################# // Commons @@ -63,6 +64,7 @@ @import 'main/partials/colorpicker'; @import 'main/partials/forms'; @import 'main/partials/loader'; +@import 'main/partials/context-menu'; //################################################# // Resources diff --git a/frontend/resources/styles/main/layouts/library-page.scss b/frontend/resources/styles/main/layouts/library-page.scss new file mode 100644 index 0000000000..2b169471b9 --- /dev/null +++ b/frontend/resources/styles/main/layouts/library-page.scss @@ -0,0 +1,273 @@ +.library-page { + height: 100%; + display: grid; + grid-template-rows: 40px 1fr; + grid-template-columns: 14.5rem 1fr; + grid-template-areas: "header header" "sidebar content"; + border-right: 1px solid $color-gray; + + & .main-bar { + grid-area: header; + } + + & .library-sidebar { + grid-area: sidebar; + } + + & .library-content { + grid-area: content; + overflow: hidden; + } +} + +.library-page #main-bar { + position: relative; +} + +.library-header-navigation { + display: flex; + position: absolute; + left: 0; + width: 100%; + justify-content: center; +} + +.library-header-navigation-item { + margin: 0 $size-4; + color: $color-gray; + text-transform: uppercase; + border-bottom: 1px solid transparent; + + &:hover, &.current { + color: $color-black; + border-bottom: 1px solid $color-primary; + } +} + +.library-sidebar { + background-color: $color-white; + padding: $size-2; +} + +.library-sidebar-add-item { + background-color: $color-primary; + border-radius: 2px; + border: none; + cursor: pointer; + font-size: 12px; + padding: $size-2; + width: 100%; + + &:hover { + background-color: $color-black; + color: $color-primary; + } +} + +.library-sidebar-list { + margin-top: $size-4; +} + +.library-sidebar-list-element { + padding: $size-4 $size-2; + cursor: pointer; + + & a { + color: $color-black; + } + + &:hover { + background-color: $color-primary-lighter; + } + + &.current a { + font-weight: bold; + } +} + +.library-top-menu { + width: 100%; + display: flex; + flex-direction: row; + border-bottom: 1px solid #e3e3e3; + justify-content: space-between; + padding: $size-2 1.5rem; + + svg { + width: 16px; + height: 16px; + fill: #7C7C7C; + cursor: pointer; + + &:hover { + fill: $color-primary; + } + } + + & > * { + align-items: center; + } +} + +.library-top-menu-current-element { + display: flex; +} + +.library-top-menu-current-element-name { + font-size: 15px; + line-height: 18px; + color: $color-black; + font-weight: normal; + margin-right: $size-2; +} + +.library-top-menu-current-action { + & svg { + width: 10px; + height: 10px; + } +} + +.library-top-menu-actions { + display: flex; + + .btn-dashboard { + background-color: transparent; + margin-left: $size-2; + } +} + +.library-page-cards-container { + padding: $size-2; + display: flex; + flex-wrap: wrap; + overflow: scroll; + height: 100%; + align-content: flex-start; +} + +.library-card { + margin: $size-2; + background: $color-white; + + &.library-icon, &.library-color { + width: 200px; + } + + &.library-image { + width: 300px; + } + + height: 200px; + box-shadow: 0px 2px 4px rgba(0, 0, 0, 0.1); + border-radius: 4px; + position: relative; + + & .library-card-footer-menu { + visibility: hidden; + opacity: 0; + } + + &:hover .library-card-footer-menu { + visibility: visible; + opacity: 1; + } +} + +.library-card .input-checkbox { + margin: 0; + top: $size-2; + right: $size-2; + position: absolute; + + & label { + margin: 0; + + &:before { + margin: 0; + background-color: white; + border: 1px solid #AFB2BF; + } + } +} + + +.library-card-image { + height: 136px; + + .library-color & { + height: 104px; + } + + padding: $size-2; + overflow: hidden; + text-align: center; + display: flex; + + & svg, & img { + margin: auto; + width: auto; + height: auto; + max-height: 100%; + max-width: 100%; + } +} + +.library-card-footer { + border-top: 1px solid $color-gray-lighter; + padding: $size-2 $size-2 $size-2 $size-4; + display: grid; + grid-template-rows: 50% 50%; + grid-template-columns: 1fr 16px 1px; + grid-template-areas: "name . ." "timestamp menu options"; + + .library-card.library-color & { + height: 50%; + text-align: center; + } +} + +.library-card-footer-name { + color: $color-black; + grid-area: name; + overflow: hidden; + text-overflow: ellipsis; + white-space: nowrap; +} + +.library-card-footer-timestamp { + font-size: 12px; + grid-area: timestamp; +} + +.library-card-footer-color { + font-size: 15px; + grid-area: timestamp; +} + +.library-card-footer-color-label { + color: $color-gray; + margin-right: 0.25rem; +} + +.library-card-footer-color-rgb { + color: $color-black; +} + +.library-card-footer-menu { + grid-area: menu; + cursor: pointer; + + & svg { + width: 16px; + height: 16px; + } +} + + +.library-card-footer .context-menu { + grid-area: options; + & .context-menu-items { + top: 1.5rem; + } +} diff --git a/frontend/resources/styles/main/partials/context-menu.scss b/frontend/resources/styles/main/partials/context-menu.scss new file mode 100644 index 0000000000..2a97cb07d0 --- /dev/null +++ b/frontend/resources/styles/main/partials/context-menu.scss @@ -0,0 +1,34 @@ +.context-menu { + position: relative; + visibility: hidden; + opacity: 0; + z-index: 100; +} + +.context-menu.is-open { + position: relative; + display: block; + opacity: 1; + visibility: visible; +} + +.context-menu-items { + background: $color-white; + box-shadow: 0px 2px 8px rgba(0, 0, 0, 0.25); + left: -$size-4; + min-width: 7rem; + position: absolute; + top: $size-3; +} + +.context-menu-action { + color: $color-black; + display: block; + font-size: 12px; + padding: $size-2 $size-4; + + &:hover { + color: $color-black; + background: $color-gray-lightest; + } +} diff --git a/frontend/resources/styles/main/partials/library-bar.scss b/frontend/resources/styles/main/partials/library-bar.scss index d97b08c047..ec1449ace9 100644 --- a/frontend/resources/styles/main/partials/library-bar.scss +++ b/frontend/resources/styles/main/partials/library-bar.scss @@ -9,6 +9,7 @@ background-color: $color-white; .library-bar-inside { + border-right: 1px solid $color-gray-lighter; display: flex; flex-direction: column; height: 100%; diff --git a/frontend/src/uxbox/builtins/icons.cljs b/frontend/src/uxbox/builtins/icons.cljs index b924ca0c54..8c92eb9056 100644 --- a/frontend/src/uxbox/builtins/icons.cljs +++ b/frontend/src/uxbox/builtins/icons.cljs @@ -17,6 +17,7 @@ (def align-right (icon-xref :align-right)) (def alignment (icon-xref :alignment)) (def arrow (icon-xref :arrow)) +(def arrow-down (icon-xref :arrow-down)) (def arrow-end (icon-xref :arrow-end)) (def arrow-slide (icon-xref :arrow-slide)) (def artboard (icon-xref :artboard)) diff --git a/frontend/src/uxbox/main/ui.cljs b/frontend/src/uxbox/main/ui.cljs index 637727b948..bdc69b7173 100644 --- a/frontend/src/uxbox/main/ui.cljs +++ b/frontend/src/uxbox/main/ui.cljs @@ -90,7 +90,8 @@ (:dashboard-search :dashboard-team - :dashboard-project) + :dashboard-project + :dashboard-library) (mf/element dashboard #js {:route route}) :workspace diff --git a/frontend/src/uxbox/main/ui/dashboard.cljs b/frontend/src/uxbox/main/ui/dashboard.cljs index 6e56b153ed..90a3b02b2d 100644 --- a/frontend/src/uxbox/main/ui/dashboard.cljs +++ b/frontend/src/uxbox/main/ui/dashboard.cljs @@ -16,11 +16,11 @@ [uxbox.common.exceptions :as ex] [uxbox.common.spec :as us] [uxbox.main.refs :as refs] - [uxbox.main.ui.dashboard.header :refer [header]] [uxbox.main.ui.dashboard.sidebar :refer [sidebar]] [uxbox.main.ui.dashboard.search :refer [search-page]] [uxbox.main.ui.dashboard.project :refer [project-page]] [uxbox.main.ui.dashboard.recent-files :refer [recent-files-page]] + [uxbox.main.ui.dashboard.library :refer [library-page]] [uxbox.main.ui.dashboard.profile :refer [profile-section]] [uxbox.main.ui.messages :refer [messages-widget]])) @@ -66,7 +66,6 @@ :search-term search-term :section section}] [:div.dashboard-content - [:& header] (case section :dashboard-search (mf/element search-page #js {:team-id team-id :search-term search-term}) @@ -74,6 +73,9 @@ :dashboard-team (mf/element recent-files-page #js {:team-id team-id}) + :dashboard-library + (mf/element library-page #js {:team-id team-id}) + :dashboard-project (mf/element project-page #js {:team-id team-id :project-id project-id}))]]]) diff --git a/frontend/src/uxbox/main/ui/dashboard/components/context_menu.cljs b/frontend/src/uxbox/main/ui/dashboard/components/context_menu.cljs new file mode 100644 index 0000000000..dd55fb276d --- /dev/null +++ b/frontend/src/uxbox/main/ui/dashboard/components/context_menu.cljs @@ -0,0 +1,15 @@ +(ns uxbox.main.ui.dashboard.components.context-menu + (:require + [rumext.alpha :as mf] + [uxbox.util.uuid :as uuid])) + +(mf/defc context-menu + [{ :keys [ is-open options ]}] + [:div.context-menu + { :class-name (when is-open "is-open")} + [:ul.context-menu-items + (for [[action-name action-handler] options] + [:li.context-menu-item + { :key (uuid/next)} + [:a.context-menu-action {:on-click action-handler} action-name]])]]) + diff --git a/frontend/src/uxbox/main/ui/dashboard/elements.cljs b/frontend/src/uxbox/main/ui/dashboard/elements.cljs index 2c87e6b24f..842ad0b07b 100644 --- a/frontend/src/uxbox/main/ui/dashboard/elements.cljs +++ b/frontend/src/uxbox/main/ui/dashboard/elements.cljs @@ -12,7 +12,7 @@ [uxbox.builtins.icons :as i] [rumext.core :as mx :include-macros true] [uxbox.main.ui.lightbox :as lbx] - [uxbox.main.ui.dashboard.header :refer (header)] + #_[uxbox.main.ui.dashboard.header :refer (header)] [uxbox.util.dom :as dom])) ;; --- Page Title diff --git a/frontend/src/uxbox/main/ui/dashboard/header.cljs b/frontend/src/uxbox/main/ui/dashboard/header.cljs deleted file mode 100644 index 9a56e150f7..0000000000 --- a/frontend/src/uxbox/main/ui/dashboard/header.cljs +++ /dev/null @@ -1,26 +0,0 @@ -;; 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/. -;; -;; This Source Code Form is "Incompatible With Secondary Licenses", as -;; defined by the Mozilla Public License, v. 2.0. -;; -;; Copyright (c) 2015-2020 Andrey Antukh -;; Copyright (c) 2015-2020 Juan de la Cruz - -(ns uxbox.main.ui.dashboard.header - (:require - [rumext.alpha :as mf] - [uxbox.util.i18n :as i18n :refer [t]] - [uxbox.main.ui.dashboard.profile :refer [profile-section]])) - - -;; --- Component: Header - -(mf/defc header - [{:keys [profile] :as props}] - (let [locale (i18n/use-locale)] - [:header#main-bar.main-bar - [:h1.dashboard-title "Personal"] - [:a.btn-dashboard "+ New project"]])) - diff --git a/frontend/src/uxbox/main/ui/dashboard/library.cljs b/frontend/src/uxbox/main/ui/dashboard/library.cljs new file mode 100644 index 0000000000..5cad30fec0 --- /dev/null +++ b/frontend/src/uxbox/main/ui/dashboard/library.cljs @@ -0,0 +1,136 @@ +;; 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/. +;; +;; This Source Code Form is "Incompatible With Secondary Licenses", as +;; defined by the Mozilla Public License, v. 2.0. +;; +;; Copyright (c) 2015-2020 Andrey Antukh +;; Copyright (c) 2015-2020 Juan de la Cruz + +(ns uxbox.main.ui.dashboard.library + (:require + [lentes.core :as l] + [rumext.alpha :as mf] + [uxbox.builtins.icons :as i] + [uxbox.main.store :as st] + [uxbox.main.refs :as refs] + [uxbox.util.i18n :as i18n :refer [t tr]] + [uxbox.main.ui.dashboard.components.context-menu :refer [context-menu]])) + +(mf/defc library-header + [{:keys [profile] :as props}] + (let [locale (i18n/use-locale)] + [:header#main-bar.main-bar + [:h1.dashboard-title "Libraries"] + [:nav.library-header-navigation + [:a.library-header-navigation-item "Icons"] + [:a.library-header-navigation-item "Images"] + [:a.library-header-navigation-item "Colors"]]])) + +(mf/defc library-sidebar + [] + [:aside.library-sidebar + [:button.library-sidebar-add-item + {:type "button"} + "+ New icon library"] + [:ul.library-sidebar-list + [:li.library-sidebar-list-element [:a "Ecometer"]] + [:li.library-sidebar-list-element [:a "Tipi"]] + [:li.library-sidebar-list-element [:a "Taiga (inspirational)"]] + [:li.library-sidebar-list-element [:a "DKT photo assets"]]]]) + +(mf/defc library-top-menu + [] + (let [state (mf/use-state {:is-open false})] + [:header.library-top-menu + [:div.library-top-menu-current-element + [:h2.library-top-menu-current-element-name "UXBOX"] + [:a.library-top-menu-current-action + { :on-click #(swap! state update :is-open not)} + [:span i/arrow-down]] + [:& context-menu {:is-open (:is-open @state) + :options [["Rename" #(println "Rename")] + ["Delete" #(println "Delete")]]}]] + + [:div.library-top-menu-actions + [:a i/trash] + [:a.btn-dashboard "+ New icon"]]])) + +(mf/defc library-icon-card [] + (let [state (mf/use-state {:is-open false})] + [:div.library-card.library-icon + [:div.input-checkbox.check-primary + [:input {:type "checkbox" + :id "card" + :on-change #(println "toggle-selection") + #_(:checked false)}] + [:label {:for "card"}]] + [:div.library-card-image i/trash] + [:div.library-card-footer + [:div.library-card-footer-name "my-dear-icon.svg"] + [:div.library-card-footer-timestamp "Less than 5 seconds ago"] + [:div.library-card-footer-menu + { :on-click #(swap! state update :is-open not) } + i/actions] + [:& context-menu {:is-open (:is-open @state) + :options [["Delete" #(println "Delete")]]}]]])) + +(mf/defc library-image-card [] + (let [state (mf/use-state {:is-open false})] + [:div.library-card.library-image + [:div.input-checkbox.check-primary + [:input {:type "checkbox" + :id "card" + :on-change #(println "toggle-selection") + #_(:checked false)}] + [:label {:for "card"}]] + [:div.library-card-image + [:img {:src "https://www.placecage.com/200/200"}]] + [:div.library-card-footer + [:div.library-card-footer-name "my-dear-icon.svg"] + [:div.library-card-footer-timestamp "Less than 5 seconds ago"] + [:div.library-card-footer-menu + { :on-click #(swap! state update :is-open not) } + i/actions] + [:& context-menu {:is-open (:is-open @state) + :options [["Delete" #(println "Delete")]]}]]])) + +(mf/defc library-color-card [] + (let [state (mf/use-state {:is-open false})] + [:div.library-card.library-color + [:div.input-checkbox.check-primary + [:input {:type "checkbox" + :id "card" + :on-change #(println "toggle-selection") + #_(:checked false)}] + [:label {:for "card"}]] + [:div.library-card-image + { :style { :background-color "#9B78FF" }}] + [:div.library-card-footer + #_[:* + [:div.library-card-footer-name "my-dear-icon.svg"] + [:div.library-card-footer-timestamp "Less than 5 seconds ago"]] + [:* + [:div.library-card-footer-name "#9B78FF"] + [:div.library-card-footer-color + [:span.library-card-footer-color-label "RGB"] + [:span.library-card-footer-color-rgb "128, 128, 128"]]] + [:div.library-card-footer-menu + { :on-click #(swap! state update :is-open not) } + i/actions] + [:& context-menu {:is-open (:is-open @state) + :options [["Delete" #(println "Delete")]]}]]])) + +(mf/defc library-page + [{:keys [team-id]}] + [:div.library-page + [:& library-header] + [:& library-sidebar] + [:section.library-content + [:& library-top-menu] + [:div.library-page-cards-container + (for [_ (range 0 10)] + #_[:& library-icon-card] + #_[:& library-image-card] + [:& library-color-card])]]]) diff --git a/frontend/src/uxbox/main/ui/dashboard/recent_files.cljs b/frontend/src/uxbox/main/ui/dashboard/recent_files.cljs index 50210b3361..b781330ba4 100644 --- a/frontend/src/uxbox/main/ui/dashboard/recent_files.cljs +++ b/frontend/src/uxbox/main/ui/dashboard/recent_files.cljs @@ -39,7 +39,14 @@ (-> (l/key :recent-files) (l/derive st/state))) -;; --- Component: Drafts Page +;; --- Component: Recent files + +(mf/defc recent-files-header + [{:keys [profile] :as props}] + (let [locale (i18n/use-locale)] + [:header#main-bar.main-bar + [:h1.dashboard-title "Recent"] + [:a.btn-dashboard "+ New project"]])) (mf/defc recent-project [{:keys [project files first? locale] :as props}] @@ -70,11 +77,13 @@ recent-files (mf/deref recent-files-ref) locale (i18n/use-locale)] (when (and projects recent-files) - [:section.recent-files-page - (for [project projects] - [:& recent-project {:project project - :locale locale - :key (:id project) - :files (get recent-files (:id project)) - :first? (= project (first projects))}])]))) + [:* + [:& recent-files-header] + [:section.recent-files-page + (for [project projects] + [:& recent-project {:project project + :locale locale + :key (:id project) + :files (get recent-files (:id project)) + :first? (= project (first projects))}])]]))) diff --git a/frontend/src/uxbox/main/ui/dashboard/sidebar.cljs b/frontend/src/uxbox/main/ui/dashboard/sidebar.cljs index 5bdcc5debe..5a28e755d9 100644 --- a/frontend/src/uxbox/main/ui/dashboard/sidebar.cljs +++ b/frontend/src/uxbox/main/ui/dashboard/sidebar.cljs @@ -24,7 +24,6 @@ [uxbox.main.ui.keyboard :as kbd] [uxbox.main.ui.confirm :refer [confirm-dialog]] [uxbox.main.ui.dashboard.common :as common] - [uxbox.main.ui.dashboard.header :refer [header]] [uxbox.main.ui.messages :refer [messages-widget]] [uxbox.util.dom :as dom] [uxbox.util.i18n :as i18n :refer [t tr]] @@ -96,6 +95,8 @@ drafts? (and (= selected-section :dashboard-project) (= selected-team-id (:default-team-id profile)) (= selected-project-id (:default-project-id profile))) + library? (and (= selected-section :dashboard-library) + (= selected-team-id (:default-team-id profile))) locale (i18n/use-locale)] [:ul.library-elements [:li.recent-projects @@ -113,6 +114,8 @@ [:li + {:on-click #(st/emit! (rt/nav :dashboard-library {:team-id team-id})) + :class-name (when library? "current")} i/icon-set [:span.element-title (t locale "dashboard.sidebar.libraries")]]