diff --git a/app/components/DocumentList.js b/app/components/DocumentList.js index 78c67d7f..d6e8861f 100644 --- a/app/components/DocumentList.js +++ b/app/components/DocumentList.js @@ -7,12 +7,14 @@ import ArrowKeyNavigation from 'boundless-arrow-key-navigation'; type Props = { documents: Document[], showCollection?: boolean, + showPublished?: boolean, limit?: number, }; export default function DocumentList({ limit, showCollection, + showPublished, documents, }: Props) { const items = limit ? documents.splice(0, limit) : documents; @@ -27,6 +29,7 @@ export default function DocumentList({ key={document.id} document={document} showCollection={showCollection} + showPublished={showPublished} /> ))} diff --git a/app/components/DocumentPreview/DocumentPreview.js b/app/components/DocumentPreview/DocumentPreview.js index d595c772..e5ca56f3 100644 --- a/app/components/DocumentPreview/DocumentPreview.js +++ b/app/components/DocumentPreview/DocumentPreview.js @@ -15,6 +15,7 @@ type Props = { highlight?: ?string, context?: ?string, showCollection?: boolean, + showPublished?: boolean, ref?: *, }; @@ -133,6 +134,7 @@ class DocumentPreview extends React.Component { const { document, showCollection, + showPublished, highlight, context, ...rest @@ -173,6 +175,7 @@ class DocumentPreview extends React.Component { ); diff --git a/app/components/DocumentPreview/components/PublishingInfo.js b/app/components/DocumentPreview/components/PublishingInfo.js index 1adfcb46..7723f613 100644 --- a/app/components/DocumentPreview/components/PublishingInfo.js +++ b/app/components/DocumentPreview/components/PublishingInfo.js @@ -19,11 +19,12 @@ const Modified = styled.span` type Props = { collection?: Collection, + showPublished?: boolean, document: Document, views?: number, }; -function PublishingInfo({ collection, document }: Props) { +function PublishingInfo({ collection, showPublished, document }: Props) { const { modifiedSinceViewed, updatedAt, @@ -35,7 +36,7 @@ function PublishingInfo({ collection, document }: Props) { return ( - {publishedAt && neverUpdated ? ( + {publishedAt && (neverUpdated || showPublished) ? ( {updatedBy.name} published @@ -48,7 +49,7 @@ function PublishingInfo({ collection, document }: Props) { ) : ( -  modified )} diff --git a/app/components/PaginatedDocumentList.js b/app/components/PaginatedDocumentList.js index 8b419596..e5f9ea3d 100644 --- a/app/components/PaginatedDocumentList.js +++ b/app/components/PaginatedDocumentList.js @@ -11,6 +11,7 @@ import { ListPlaceholder } from 'components/LoadingPlaceholder'; type Props = { showCollection?: boolean, + showPublished?: boolean, documents: Document[], fetch: (options: ?Object) => Promise<*>, options?: Object, @@ -64,11 +65,15 @@ class PaginatedDocumentList extends React.Component { }; render() { - const { showCollection, documents } = this.props; + const { showCollection, showPublished, documents } = this.props; return this.isLoaded || documents.length ? ( - + {this.allowLoadMore && ( )} diff --git a/app/components/Sidebar/components/CollectionLink.js b/app/components/Sidebar/components/CollectionLink.js index 252490cc..48b056da 100644 --- a/app/components/Sidebar/components/CollectionLink.js +++ b/app/components/Sidebar/components/CollectionLink.js @@ -59,6 +59,7 @@ class CollectionLink extends React.Component { hideDisclosure menuOpen={this.menuOpen} label={collection.name} + exact={false} menu={ props.theme.slate}; letter-spacing: 0.04em; - margin-right: 20px; + margin-right: 24px; padding-bottom: 8px; + + &:hover { + color: ${props => props.theme.slateDark}; + } `; function Tab(props: *) { const activeStyle = { paddingBottom: '5px', borderBottom: `3px solid ${props.theme.slateLight}`, + color: props.theme.slate, }; return ; diff --git a/app/routes.js b/app/routes.js index a7c6a2d0..19061959 100644 --- a/app/routes.js +++ b/app/routes.js @@ -68,6 +68,7 @@ export default function Routes() { component={Zapier} /> + { this.props.ui.setActiveCollection(collection); this.collection = collection; - await Promise.all([ - this.props.documents.fetchRecentlyUpdated({ - limit: 10, - collection: id, - }), - this.props.documents.fetchPinned({ - collection: id, - }), - ]); + await this.props.documents.fetchPinned({ + collection: id, + }); } this.isFetching = false; @@ -124,15 +122,14 @@ class CollectionScene extends React.Component { } render() { + const { documents } = this.props; + if (!this.isFetching && !this.collection) { return this.renderNotFound(); } const pinnedDocuments = this.collection - ? this.props.documents.pinnedInCollection(this.collection.id) - : []; - const recentDocuments = this.collection - ? this.props.documents.recentlyUpdatedInCollection(this.collection.id) + ? documents.pinnedInCollection(this.collection.id) : []; const hasPinnedDocuments = !!pinnedDocuments.length; const collection = this.collection; @@ -207,8 +204,62 @@ class CollectionScene extends React.Component { )} - Recently edited - + + + Recently updated + + + Recently published + + + Least recently updated + + + A–Z + + + + + + + + + + + + + + + + )} diff --git a/app/scenes/Dashboard.js b/app/scenes/Dashboard.js index 47114723..8d78e485 100644 --- a/app/scenes/Dashboard.js +++ b/app/scenes/Dashboard.js @@ -12,8 +12,8 @@ import CenteredContent from 'components/CenteredContent'; import PageTitle from 'components/PageTitle'; import Tabs from 'components/Tabs'; import Tab from 'components/Tab'; -import TipInvite from 'components/TipInvite'; import PaginatedDocumentList from '../components/PaginatedDocumentList'; +import TipInvite from 'components/TipInvite'; type Props = { documents: DocumentsStore, diff --git a/app/stores/DocumentsStore.js b/app/stores/DocumentsStore.js index ddf53e8f..a30404c0 100644 --- a/app/stores/DocumentsStore.js +++ b/app/stores/DocumentsStore.js @@ -55,18 +55,42 @@ export default class DocumentsStore extends BaseStore { ); } + publishedInCollection(collectionId: string): Document[] { + return filter( + Array.from(this.data.values()), + document => + document.collectionId === collectionId && !!document.publishedAt + ); + } + + leastRecentlyUpdatedInCollection(collectionId: string): Document[] { + return orderBy( + this.publishedInCollection(collectionId), + 'updatedAt', + 'asc' + ); + } + recentlyUpdatedInCollection(collectionId: string): Document[] { return orderBy( - filter( - Array.from(this.data.values()), - document => - document.collectionId === collectionId && !!document.publishedAt - ), + this.publishedInCollection(collectionId), 'updatedAt', 'desc' ); } + recentlyPublishedInCollection(collectionId: string): Document[] { + return orderBy( + this.publishedInCollection(collectionId), + 'publishedAt', + 'desc' + ); + } + + alphabeticalInCollection(collectionId: string): Document[] { + return naturalSort(this.publishedInCollection(collectionId), 'title'); + } + @computed get starred(): Document[] { return filter(this.orderedData, d => d.starred); @@ -126,6 +150,35 @@ export default class DocumentsStore extends BaseStore { return data; }; + @action + fetchAlphabetical = async (options: ?PaginationParams): Promise<*> => { + return this.fetchNamedPage('list', { + sort: 'title', + direction: 'ASC', + ...options, + }); + }; + + @action + fetchLeastRecentlyUpdated = async ( + options: ?PaginationParams + ): Promise<*> => { + return this.fetchNamedPage('list', { + sort: 'updatedAt', + direction: 'ASC', + ...options, + }); + }; + + @action + fetchRecentlyPublished = async (options: ?PaginationParams): Promise<*> => { + return this.fetchNamedPage('list', { + sort: 'publishedAt', + direction: 'DESC', + ...options, + }); + }; + @action fetchRecentlyViewed = async (options: ?PaginationParams): Promise<*> => { const data = await this.fetchNamedPage('viewed', options); diff --git a/app/utils/routeHelpers.js b/app/utils/routeHelpers.js index d271a96b..1c3c0311 100644 --- a/app/utils/routeHelpers.js +++ b/app/utils/routeHelpers.js @@ -14,8 +14,10 @@ export function newCollectionUrl(): string { return '/collections/new'; } -export function collectionUrl(collectionId: string): string { - return `/collections/${collectionId}`; +export function collectionUrl(collectionId: string, section: ?string): string { + const path = `/collections/${collectionId}`; + if (section) return `${path}/${section}`; + return path; } export function documentUrl(doc: Document): string {