0
Fork 0
mirror of https://github.com/penpot/penpot.git synced 2025-04-16 08:51:32 -05:00

🕐 adds recent opened files screen

This commit is contained in:
alonso.torres 2020-03-12 13:26:58 +01:00 committed by Andrey Antukh
parent 1ffca33be9
commit 561560ae04
20 changed files with 437 additions and 250 deletions

View file

@ -21,6 +21,7 @@
(require 'uxbox.services.queries.files)
(require 'uxbox.services.queries.pages)
(require 'uxbox.services.queries.profile)
(require 'uxbox.services.queries.recent-files)
;; (require 'uxbox.services.queries.user-attrs)
)

View file

@ -20,7 +20,9 @@
(def ^:private sql:projects
"with projects as (
select p.*
select p.*,
(select count(*) from file as f
where f.project_id = p.id and deleted_at is null) as file_count
from project as p
inner join team_profile_rel as tpr on (tpr.team_id = p.team_id)
where tpr.profile_id = $1
@ -28,7 +30,9 @@
tpr.is_owner = true or
tpr.can_edit = true)
union
select p.*
select p.*,
(select count(*) from file as f
where f.project_id = p.id and deleted_at is null)
from project as p
inner join project_profile_rel as ppr on (ppr.project_id = p.id)
where ppr.profile_id = $1
@ -47,7 +51,10 @@
(s/def ::projects-by-team
(s/keys :req-un [::profile-id ::team-id]))
(sq/defquery ::projects-by-team
[{:keys [profile-id team-id] :as params}]
(defn projects-by-team [profile-id team-id]
(db/query db/pool [sql:projects profile-id team-id]))
(sq/defquery ::projects-by-team
[{:keys [profile-id team-id]}]
(projects-by-team profile-id team-id))

View file

@ -0,0 +1,58 @@
;; 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) 2019-2020 Andrey Antukh <niwi@niwi.nz>
(ns uxbox.services.queries.recent-files
(:require
[clojure.spec.alpha :as s]
[promesa.core :as p]
[uxbox.db :as db]
[uxbox.common.spec :as us]
[uxbox.services.queries :as sq]
[uxbox.services.queries.projects :refer [ projects-by-team ]]
[uxbox.services.queries.files :refer [ decode-row ]]))
(def ^:private sql:project_files_recent
"select distinct
f.*,
array_agg(pg.id) over pages_w as pages,
first_value(pg.data) over pages_w as data
from file as f
inner join file_profile_rel as fp_r on (fp_r.file_id = f.id)
left join page as pg on (f.id = pg.file_id)
where fp_r.profile_id = $1
and f.project_id = $2
and f.deleted_at is null
and pg.deleted_at is null
and (fp_r.is_admin = true or
fp_r.is_owner = true or
fp_r.can_edit = true)
window pages_w as (partition by f.id order by pg.created_at
range between unbounded preceding
and unbounded following)
order by f.modified_at desc
limit 5")
(defn recent-by-project [profile-id project]
(let [project-id (:id project)]
(-> (db/query db/pool [sql:project_files_recent profile-id project-id])
(p/then (partial mapv decode-row)))))
(s/def ::team-id ::us/uuid)
(s/def ::profile-id ::us/uuid)
(s/def ::recent-files
(s/keys :req-un [::profile-id ::team-id]))
(sq/defquery ::recent-files
[{:keys [profile-id team-id]}]
(-> (projects-by-team profile-id team-id)
;; Retrieve for each proyect the 5 more recent files
(p/then #(p/all (map (partial recent-by-project profile-id) %)))
;; Change the structure so it's a map with project-id as keys
(p/then #(->> % (flatten) (group-by :project-id)))))

View file

@ -0,0 +1,3 @@
<svg width="500" height="500" viewBox="0 0 16 16" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M8.5566 0.802143C5.73484 0.832201 3.03915 2.69963 2.02385 5.31247C1.85137 5.73396 1.71601 6.17029 1.61706 6.61447C1.14241 6.64869 0.619077 6.53608 0.164899 6.73219C-0.0777895 6.90104 -0.0358054 7.27633 0.181443 7.44833C0.780549 8.19904 1.36737 8.96764 2.04494 9.64955C2.36308 9.83712 2.77377 9.62369 2.92385 9.31767C3.48353 8.60401 4.10411 7.92266 4.56258 7.14015C4.6219 6.81493 4.25454 6.5743 3.95701 6.62813C3.72094 6.61113 3.48372 6.64427 3.24811 6.6178C3.79083 4.35481 5.91004 2.56008 8.25024 2.3836C10.2173 2.20058 12.271 3.13167 13.395 4.7633C14.5033 6.33202 14.7495 8.4588 13.9626 10.2177C13.2423 11.9016 11.6562 13.1891 9.84502 13.5267C8.12195 13.8686 6.25055 13.3618 4.94453 12.1845C4.72991 11.996 4.51061 11.7519 4.19717 11.7614C3.74737 11.7292 3.35166 12.1464 3.38782 12.5871C3.38929 12.8543 3.57566 13.0629 3.77045 13.2236C5.77493 15.1876 9.00192 15.7487 11.5753 14.6313C13.6464 13.7664 15.277 11.9044 15.7901 9.72495C16.3003 7.68095 15.8731 5.41472 14.5896 3.72888C13.2349 1.90511 10.9825 0.742088 8.68867 0.802015C8.6446 0.801698 8.60061 0.801698 8.5566 0.802111V0.802143ZM8.71661 3.18016C8.24963 3.18124 7.887 3.67092 7.98284 4.11561C7.9743 5.49196 7.92351 6.68183 8.00108 8.05586C8.00108 8.56496 8.40611 8.76793 9.00003 8.76793C10.1984 8.7713 11.4021 8.82853 12.5972 8.72777C13.1187 8.5769 13.2746 7.83426 12.8979 7.46167C12.6991 7.22791 12.3702 7.18867 12.0829 7.22552L9.54781 7.20217C9.52157 6.02587 9.5815 4.84522 9.47376 3.67232C9.36598 3.36623 9.03677 3.17047 8.71657 3.18013L8.71661 3.18016Z" fill="#1F1F1F"/>
</svg>

After

Width:  |  Height:  |  Size: 1.6 KiB

View file

@ -60,12 +60,14 @@
"en" : "Libraries"
}
},
"dashboard.sidebar.recent": "Recent",
"dashboard.sidebar.personal" : {
"used-in" : [ "src/uxbox/main/ui/dashboard/sidebar.cljs:104" ],
"translations" : {
"en" : "Personal"
}
},
"dashboard.grid.empty-files": "You still have no files here",
"ds.accept" : {
"used-in" : [ "src/uxbox/main/ui/workspace/sidebar/history.cljs:113" ],
"translations" : {

View file

@ -12,6 +12,12 @@ $medium: 15px;
$big: 20px;
$x-big: 30px;
// New sizes
$size-1: 0.25rem;
$size-2: 0.5rem;
$size-3: 0.8rem;
$size-4: 1rem;
// Border radius
$br-small: 3px;
$br-medium: 5px;

View file

@ -27,6 +27,8 @@
@import 'common/base';
@import 'main/layouts/main-layout';
@import 'main/layouts/login';
@import 'main/layouts/projects-page';
@import 'main/layouts/recent-files-page';
//#################################################
// Commons

View file

@ -0,0 +1,3 @@
.projects-page {
padding: 1rem;
}

View file

@ -0,0 +1,43 @@
.recent-files-page {
overflow: scroll;
height: 100%;
}
.recent-files-row {
padding: 1rem;
border-top: 1px solid $color-gray-10;
&:hover {
background-color: white;
}
&.first {
border-top: none;
}
}
.recent-files-row-title {
display: flex;
flex-direction: row;
margin-left: $medium;
margin-top: $medium;
}
.recent-files-row-title-name, .recent-files-row-title-info {
font-size: 15px;
line-height: 1rem;
font-weight: unset;
}
.recent-files-row-title-name {
color: black;
margin-right: $medium;
}
.recent-files-row-title-info {
}
.recent-files-empty {
margin: 30px;
font-size: 20px
}

View file

@ -10,9 +10,6 @@
flex-direction: column;
font-size: $fs14;
height: 100%;
padding: $medium;
// ACTIVITY BAR PADDING
//padding: $medium 250px $medium $medium;
.dashboard-title {
margin: $medium 0;
@ -75,15 +72,13 @@
.dashboard-grid-content {
display: flex;
height: 100%;
min-height: 60vh;
overflow: scroll;
width: 100%;
.dashboard-grid-row {
display: flex;
flex-wrap: wrap;
margin-bottom: auto;
width: 100%;
align-content: flex-start;
}
.grid-item {
@ -94,12 +89,28 @@
flex-direction: column;
flex-shrink: 0;
height: 200px;
margin: $medium $medium 0 $medium;
margin: $medium;
max-width: 300px;
min-width: 260px;
position: relative;
text-align: center;
width: 18%;
box-shadow: 0px 2px 4px rgba(0, 0, 0, 0.1);
& .overlay {
border-radius: 4px;
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%;
@ -145,9 +156,10 @@
}
&.add-project {
&.add-file {
border: 1px dashed $color-gray-light;
justify-content: center;
box-shadow: none;
span {
color: $color-gray-60;
@ -399,5 +411,18 @@
}
}
}
.grid-files-empty {
align-items: center;
border: 1px dashed $color-gray-20;
display: flex;
flex-direction: column;
margin: $size-4;
padding: 3rem;
width: 100%;
}
.grid-files-link-text {
color: $color-black;
}

View file

@ -49,7 +49,7 @@
display: flex;
flex-direction: column;
height: calc(95% - 1rem);
margin-bottom: 1rem;
margin-bottom: $size-4;
overflow-y: auto;
padding-bottom: 20px;
@ -58,15 +58,14 @@
cursor: pointer;
display: flex;
flex-shrink: 0;
padding: $medium $small;
padding: $size-4 $size-2;
svg {
border-radius: 3px;
fill: $color-black;
height: 24px;
margin-right: $small;
padding: $x-small;
width: 24px;
margin-right: 8px;
height: $size-4;
width: $size-4;
}
span.element-title {
@ -81,7 +80,6 @@
border-top: 1px solid $color-gray-10;
svg {
background-color: $color-black;
fill: $color-white;
}
@ -90,22 +88,30 @@
}
}
& .edit-wrapper {
display: flex;
}
input.element-title {
border: 0;
height: 30px;
padding: 5px;
margin: 0;
width: 100%;
background-color: $color-white;
}
.close {
background: $color-gray-50;
background-color: $color-white;
cursor: pointer;
padding: 5px 10px;
padding: 3px 5px;
svg {
fill: $color-gray;
height: 20px;
height: 15px;
transform: rotate(45deg) translateY(7px);
width: 20px;
width: 15px;
margin: 0;
}
}
@ -114,39 +120,20 @@
font-style: italic;
}
&:hover {
background-color: $color-primary;
&:hover,
&.current {
background-color: $color-primary-lighter;
color: $color-gray-60;
}
&.current {
svg {
fill: $color-black;
}
span.element-title,
.element-subtitle {
color: $color-gray-60;
font-weight: bold;
}
input.element-title {
color: $color-gray-dark;
}
}
}
}
}
}
.projects-row {
align-items: center;
display: flex;
padding: $medium;
padding: $size-2;
span {
color: $color-gray-30;
@ -166,8 +153,8 @@
svg {
fill: $color-gray-60;
height: 13px;
width: 13px;
height: $size-2;
width: $size-2;
}
&:hover {
@ -184,7 +171,7 @@
align-items: center;
border: 1px solid $color-gray-10;
display: flex;
margin: $medium;
margin: $size-2;
.input-text {
background: $color-white;

View file

@ -74,6 +74,7 @@
(def ungroup (icon-xref :ungroup))
(def unlock (icon-xref :unlock))
(def user (icon-xref :user))
(def recent (icon-xref :recent))
(def loader-pencil
(html

View file

@ -57,9 +57,10 @@
(declare fetch-files)
(declare fetch-projects)
(declare fetch-recent-files)
(def initialize-drafts
(ptk/reify ::initialize
(ptk/reify ::initialize-drafts
ptk/UpdateEvent
(update [_ state]
(let [profile (:profile state)]
@ -77,7 +78,7 @@
(defn initialize-team
[team-id]
(us/verify ::us/uuid team-id)
(ptk/reify ::initialize
(ptk/reify ::initialize-team
ptk/UpdateEvent
(update [_ state]
(update state :dashboard-local assoc
@ -87,14 +88,15 @@
ptk/WatchEvent
(watch [_ state stream]
(let [local (:dashboard-local state)]
(rx/of (fetch-projects (:team-id local)))))))
(rx/of (fetch-projects (:team-id local))
(fetch-recent-files (:team-id local)))))))
(defn initialize-project
[team-id project-id]
(us/verify ::us/uuid team-id)
(us/verify ::us/uuid project-id)
(ptk/reify ::initialize
(ptk/reify ::initialize-project
ptk/UpdateEvent
(update [_ state]
(update state :dashboard-local assoc
@ -156,6 +158,26 @@
files (d/index-by :id files)]
(assoc state :files files)))))
;; --- Fetch recent files
(declare recent-files-fetched)
(defn fetch-recent-files
[team-id]
(ptk/reify ::fetch-recent-files
ptk/WatchEvent
(watch [_ state stream]
(let [params {:team-id team-id}]
(->> (rp/query :recent-files params)
(rx/map recent-files-fetched))))))
(defn recent-files-fetched
[recent-files]
(ptk/reify ::recent-files-fetched
ptk/UpdateEvent
(update [_ state]
(assoc state :recent-files recent-files))))
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; Data Modification
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
@ -239,12 +261,12 @@
(declare file-created)
(def create-file
(defn create-file
[project-id]
(ptk/reify ::create-draft-file
ptk/WatchEvent
(watch [_ state stream]
(let [name (str "New File " (gensym "p"))
project-id (get-in state [:dashboard-local :project-id])
params {:name name :project-id project-id}]
(->> (rp/mutation! :create-file params)
(rx/map file-created))))))
@ -255,7 +277,9 @@
(ptk/reify ::create-draft-file
ptk/UpdateEvent
(update [this state]
(update state :files assoc (:id data) data))))
(-> state
(update :files assoc (:id data) data)
(update :recent-files update (:project-id data) conj data)))))
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

View file

@ -25,7 +25,7 @@
{:x 0 :y 0
:width "100%"
:height "100%"
:fill "#b1b2b5"}])
:fill "#AFB2BF"}])
(defn- calculate-dimensions
[data]

View file

@ -19,11 +19,11 @@
[uxbox.main.ui.dashboard.header :refer [header]]
[uxbox.main.ui.dashboard.sidebar :refer [sidebar]]
[uxbox.main.ui.dashboard.project :refer [project-page]]
[uxbox.main.ui.dashboard.team :refer [team-page]]
[uxbox.main.ui.dashboard.recent-files :refer [recent-files-page]]
[uxbox.main.ui.dashboard.profile :refer [profile-section]]
[uxbox.main.ui.messages :refer [messages-widget]]))
(defn- ^boolean uuid-str?
(defn ^boolean uuid-str?
[s]
(and (string? s)
(boolean (re-seq us/uuid-rx s))))
@ -64,7 +64,7 @@
[:& header]
(case section
:dashboard-team
(mf/element team-page #js {:team-id team-id})
(mf/element recent-files-page #js {:team-id team-id})
:dashboard-project
(mf/element project-page #js {:team-id team-id

View file

@ -0,0 +1,127 @@
(ns uxbox.main.ui.dashboard.grid
(:refer-clojure :exclude [sort-by])
(:require
[cuerdas.core :as str]
[rumext.alpha :as mf]
[uxbox.builtins.icons :as i]
[uxbox.main.data.projects :as udp]
[uxbox.main.data.dashboard :as dsh]
[uxbox.main.store :as st]
[uxbox.main.exports :as exports]
[uxbox.main.ui.modal :as modal]
[uxbox.main.ui.keyboard :as kbd]
[uxbox.main.ui.confirm :refer [confirm-dialog]]
[uxbox.util.dom :as dom]
[uxbox.util.i18n :as i18n :refer [t tr]]
[uxbox.util.time :as dt]))
;; --- Helpers
(defn sort-by
[ordering files]
(case ordering
:name (cljs.core/sort-by :name files)
:created (reverse (cljs.core/sort-by :created-at files))
:modified (reverse (cljs.core/sort-by :modified-at files))
files))
(defn contains-term?
[phrase term]
(let [term (name term)]
(str/includes? (str/lower phrase) (str/trim (str/lower term)))))
(defn filter-by
[term files]
(if (str/blank? term)
files
(filter #(contains-term? (:name %) term) files)))
;; --- Grid Item Thumbnail
(mf/defc grid-item-thumbnail
[{:keys [file] :as props}]
[:div.grid-item-th
[:& exports/page-svg {:data (:data file)
:width "290"
:height "150"}]])
;; --- Grid Item
(mf/defc grid-item-metadata
[{:keys [modified-at]}]
(let [locale (i18n/use-locale)
time (dt/timeago modified-at {:locale locale})]
(str (t locale "ds.updated-at" time))))
(mf/defc grid-item
{:wrap [mf/wrap-memo]}
[{:keys [file] :as props}]
(let [local (mf/use-state {})
on-navigate #(st/emit! (udp/go-to (:id file)))
delete-fn #(st/emit! nil (udp/delete-file (:id file)))
on-delete #(do
(dom/stop-propagation %)
(modal/show! confirm-dialog {:on-accept delete-fn}))
on-blur #(let [name (-> % dom/get-target dom/get-value)]
(st/emit! (udp/rename-file (:id file) name))
(swap! local assoc :edition false))
on-key-down #(when (kbd/enter? %) (on-blur %))
on-edit #(do
(dom/stop-propagation %)
(dom/prevent-default %)
(swap! local assoc :edition true))]
[:div.grid-item.project-th {:on-click on-navigate}
[:div.overlay]
[:& grid-item-thumbnail {:file file}]
[:div.item-info
(if (:edition @local)
[:input.element-name {:type "text"
:auto-focus true
:on-key-down on-key-down
:on-blur on-blur
;; :on-click on-edit
:default-value (:name file)}]
[:h3 (:name file)])
[:& grid-item-metadata {:modified-at (:modified-at file)}]]
[:div.project-th-actions
;; [:div.project-th-icon.pages
;; i/page
;; #_[:span (:total-pages project)]]
;; [:div.project-th-icon.comments
;; i/chat
;; [:span "0"]]
[:div.project-th-icon.edit
{:on-click on-edit}
i/pencil]
[:div.project-th-icon.delete
{:on-click on-delete}
i/trash]]]))
;; --- Grid
(mf/defc grid
[{:keys [id opts files hide-new?] :as props}]
(let [locale (i18n/use-locale)
order (:order opts :modified)
filter (:filter opts "")
files (->> files
(filter-by filter)
(sort-by order))
on-click #(do
(dom/prevent-default %)
(st/emit! (dsh/create-file id)))]
[:section.dashboard-grid
[:div.dashboard-grid-content
(if (> (count files) 0)
[:div.dashboard-grid-row
(when (not hide-new?)
[:div.grid-item.add-file {:on-click on-click}
[:span (tr "ds.new-file")]])
(for [item files]
[:& grid-item {:file item :key (:id item)}])]
[:div.grid-files-empty
[:div.grid-files-desc (t locale "dashboard.grid.empty-files")]
[:div.grid-files-link
[:a.grid-files-link-text {:on-click on-click} (t locale "ds.new-file")]]])]]))

View file

@ -11,154 +11,24 @@
(ns uxbox.main.ui.dashboard.project
(:refer-clojure :exclude [sort-by])
(:require
[cuerdas.core :as str]
[lentes.core :as l]
[rumext.alpha :as mf]
[uxbox.builtins.icons :as i]
[uxbox.main.constants :as c]
[uxbox.main.data.projects :as udp]
[uxbox.main.data.dashboard :as dsh]
[uxbox.main.store :as st]
[uxbox.main.exports :as exports]
[uxbox.main.refs :as refs]
[uxbox.main.ui.modal :as modal]
[uxbox.main.ui.keyboard :as kbd]
[uxbox.main.ui.confirm :refer [confirm-dialog]]
[uxbox.main.ui.dashboard.header :refer [header]]
[uxbox.main.ui.dashboard.sidebar :refer [sidebar]]
[uxbox.main.ui.messages :refer [messages-widget]]
[uxbox.util.dom :as dom]
[uxbox.util.i18n :as i18n :refer [t tr]]
[uxbox.util.router :as rt]
[uxbox.util.time :as dt]))
;; --- Helpers
(defn sort-by
[ordering files]
(case ordering
:name (cljs.core/sort-by :name files)
:created (reverse (cljs.core/sort-by :created-at files))
:modified (reverse (cljs.core/sort-by :modified-at files))
files))
(defn contains-term?
[phrase term]
(let [term (name term)]
(str/includes? (str/lower phrase) (str/trim (str/lower term)))))
(defn filter-by
[term files]
(if (str/blank? term)
files
(filter #(contains-term? (:name %) term) files)))
;; --- Grid Item Thumbnail
(mf/defc grid-item-thumbnail
[{:keys [file] :as props}]
[:div.grid-item-th
[:& exports/page-svg {:data (:data file)
:width "290"
:height "150"}]])
;; --- Grid Item
(mf/defc grid-item-metadata
[{:keys [modified-at]}]
(let [locale (i18n/use-locale)
time (dt/timeago modified-at {:locale locale})]
(str (t locale "ds.updated-at" time))))
(mf/defc grid-item
{:wrap [mf/wrap-memo]}
[{:keys [file] :as props}]
(let [local (mf/use-state {})
on-navigate #(st/emit! (udp/go-to (:id file)))
delete-fn #(st/emit! nil (udp/delete-file (:id file)))
on-delete #(do
(dom/stop-propagation %)
(modal/show! confirm-dialog {:on-accept delete-fn}))
on-blur #(let [name (-> % dom/get-target dom/get-value)]
(st/emit! (udp/rename-file (:id file) name))
(swap! local assoc :edition false))
on-key-down #(when (kbd/enter? %) (on-blur %))
on-edit #(do
(dom/stop-propagation %)
(dom/prevent-default %)
(swap! local assoc :edition true))]
[:div.grid-item.project-th {:on-click on-navigate}
[:& grid-item-thumbnail {:file file}]
[:div.item-info
(if (:edition @local)
[:input.element-name {:type "text"
:auto-focus true
:on-key-down on-key-down
:on-blur on-blur
;; :on-click on-edit
:default-value (:name file)}]
[:h3 (:name file)])
[:& grid-item-metadata {:modified-at (:modified-at file)}]]
[:div.project-th-actions
;; [:div.project-th-icon.pages
;; i/page
;; #_[:span (:total-pages project)]]
;; [:div.project-th-icon.comments
;; i/chat
;; [:span "0"]]
[:div.project-th-icon.edit
{:on-click on-edit}
i/pencil]
[:div.project-th-icon.delete
{:on-click on-delete}
i/trash]]]))
;; --- Grid
(mf/defc grid
[{:keys [id opts files] :as props}]
(let [order (:order opts :modified)
filter (:filter opts "")
files (->> files
(filter-by filter)
(sort-by order))
on-click #(do
(dom/prevent-default %)
(st/emit! dsh/create-file))]
[:section.dashboard-grid
[:div.dashboard-grid-content
[:div.dashboard-grid-row
[:div.grid-item.add-project {:on-click on-click}
[:span (tr "ds.new-file")]]
(for [item files]
[:& grid-item {:file item :key (:id item)}])]]]))
;; --- Component: Project
[uxbox.main.ui.dashboard.grid :refer [grid]]))
(def files-ref
(-> (comp (l/key :files)
(l/lens vals))
(l/derive st/state)))
(def opts-iref
(-> (l/key :dashboard-projects)
(l/derive st/state)))
(mf/defc project-page
[{:keys [section team-id project-id] :as props}]
(let [opts (mf/deref opts-iref)
files (mf/deref files-ref)]
(let [files (mf/deref files-ref)]
(mf/use-effect
{:fn #(st/emit! (dsh/initialize-project team-id project-id))
:deps (mf/deps team-id project-id)})
[:section.dashboard-grid.library
[:& grid {:id project-id :opts opts :files files}]]))
[:section.projects-page
[:& grid { :id project-id :files files }]]))

View file

@ -0,0 +1,77 @@
;; 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 <niwi@niwi.nz>
;; Copyright (c) 2015-2020 Juan de la Cruz <delacruzgarciajuan@gmail.com>
(ns uxbox.main.ui.dashboard.recent-files
(:require
[lentes.core :as l]
[rumext.alpha :as mf]
[uxbox.builtins.icons :as i]
[uxbox.common.exceptions :as ex]
[uxbox.main.constants :as c]
[uxbox.main.data.projects :as udp]
[uxbox.main.data.dashboard :as dsh]
[uxbox.main.store :as st]
[uxbox.main.exports :as exports]
[uxbox.main.refs :as refs]
[uxbox.main.ui.modal :as modal]
[uxbox.main.ui.keyboard :as kbd]
[uxbox.main.ui.confirm :refer [confirm-dialog]]
[uxbox.util.dom :as dom]
[uxbox.util.i18n :as i18n :refer [t tr]]
[uxbox.util.router :as rt]
[uxbox.util.time :as dt]
[uxbox.main.ui.dashboard.grid :refer [grid]])
)
;; --- Component: Content
(def projects-ref
(-> (l/key :projects)
(l/derive st/state)))
(def recent-files-ref
(-> (l/key :recent-files)
(l/derive st/state)))
;; --- Component: Drafts Page
(mf/defc recent-files-page
[{:keys [section team-id] :as props}]
(mf/use-effect
{:fn #(st/emit! (dsh/initialize-team team-id))
:deps (mf/deps team-id)})
(let [projects (mf/deref projects-ref)
recent-files (mf/deref recent-files-ref)
locale (i18n/use-locale)]
(if projects
[:section.recent-files-page
(for [project (vals projects)]
[:div.recent-files-row
{:key (:id project)
:class-name (when (= project (first (vals projects))) "first")}
[:div.recent-files-row-title
[:h2.recent-files-row-title-name (:name project)]
[:span.recent-files-row-title-info (str (:file-count project) " files")]
(when (and recent-files (recent-files (:id project)))
(let [time (-> (project :id)
(recent-files)
(first)
:modified-at
(dt/timeago {:locale locale}))]
[:span.recent-files-row-title-info (str ", " time)]))]
[:& grid {:id (:id project)
:files (or
(and recent-files (recent-files (:id project)))
[])
:hide-new? true}]])]
[:section
[:p "empty"]])
))

View file

@ -57,12 +57,14 @@
:on-double-click on-dbl-click
:class-name (when selected? "current")}
(if (:edit @local)
[:div
[:div.edit-wrapper
[:input.element-title {:value (:name @local)
:on-change on-input
:on-key-down on-keyup}]
[:span.close {:on-click on-cancel} i/close]]
[:span.element-title name])]))
[:*
i/folder
[:span.element-title name]])]))
(def projects-iref
(-> (l/key :projects)
@ -99,8 +101,8 @@
[:li.recent-projects
{:on-click #(st/emit! (rt/nav :dashboard-team {:team-id team-id}))
:class-name (when home? "current")}
i/user
[:span.element-title (t locale "dashboard.sidebar.personal")]]
i/recent
[:span.element-title (t locale "dashboard.sidebar.recent")]]
[:li
{:on-click #(st/emit! (rt/nav :dashboard-project {:team-id team-id

View file

@ -1,51 +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 <niwi@niwi.nz>
;; Copyright (c) 2015-2020 Juan de la Cruz <delacruzgarciajuan@gmail.com>
(ns uxbox.main.ui.dashboard.team
(:require
[lentes.core :as l]
[rumext.alpha :as mf]
[uxbox.builtins.icons :as i]
[uxbox.common.exceptions :as ex]
[uxbox.main.constants :as c]
[uxbox.main.data.projects :as udp]
[uxbox.main.data.dashboard :as dsh]
[uxbox.main.store :as st]
[uxbox.main.exports :as exports]
[uxbox.main.refs :as refs]
[uxbox.main.ui.modal :as modal]
[uxbox.main.ui.keyboard :as kbd]
[uxbox.main.ui.confirm :refer [confirm-dialog]]
[uxbox.util.dom :as dom]
[uxbox.util.i18n :as i18n :refer [t tr]]
[uxbox.util.router :as rt]
[uxbox.util.time :as dt]))
;; --- Component: Content
;; (def files-ref
;; (-> (comp (l/key :files)
;; (l/lens vals))
;; (l/derive st/state)))
;; (def opts-iref
;; (-> (l/key :dashboard-projects)
;; (l/derive st/state)))
;; --- Component: Drafts Page
(mf/defc team-page
[{:keys [section team-id] :as props}]
(mf/use-effect
{:fn #(st/emit! (dsh/initialize-team team-id))
:deps (mf/deps team-id)})
[:section
[:p "TEAM PAGE"]])