diff --git a/app/models/Document.js b/app/models/Document.js index 00397a5d..c67b1c58 100644 --- a/app/models/Document.js +++ b/app/models/Document.js @@ -20,6 +20,7 @@ class Document extends BaseModel { collaborators: Array; collection: $Shape; + collectionId: string; firstViewedAt: ?string; lastViewedAt: ?string; modifiedSinceViewed: ?boolean; diff --git a/app/scenes/Collection/Collection.js b/app/scenes/Collection/Collection.js index 6cd13ab7..f2650337 100644 --- a/app/scenes/Collection/Collection.js +++ b/app/scenes/Collection/Collection.js @@ -7,6 +7,7 @@ import styled from 'styled-components'; import { newDocumentUrl } from 'utils/routeHelpers'; import CollectionsStore from 'stores/CollectionsStore'; +import DocumentsStore from 'stores/DocumentsStore'; import UiStore from 'stores/UiStore'; import Collection from 'models/Collection'; @@ -16,12 +17,14 @@ import CollectionIcon from 'components/Icon/CollectionIcon'; import LoadingListPlaceholder from 'components/LoadingListPlaceholder'; import Button from 'components/Button'; import HelpText from 'components/HelpText'; +import DocumentList from 'components/DocumentList'; import Subheading from 'components/Subheading'; import PageTitle from 'components/PageTitle'; import Flex from 'shared/components/Flex'; type Props = { ui: UiStore, + documents: DocumentsStore, collections: CollectionsStore, match: Object, }; @@ -32,23 +35,28 @@ class CollectionScene extends Component { @observable collection: ?Collection; @observable isFetching: boolean = true; - componentDidMount = () => { - this.fetchCollection(this.props.match.params.id); - }; + componentDidMount() { + this.loadContent(this.props.match.params.id); + } componentWillReceiveProps(nextProps) { if (nextProps.match.params.id !== this.props.match.params.id) { - this.fetchCollection(nextProps.match.params.id); + this.loadContent(nextProps.match.params.id); } } - fetchCollection = async (id: string) => { + loadContent = async (id: string) => { const { collections } = this.props; const collection = await collections.fetch(id); + if (collection) { this.props.ui.setActiveCollection(collection); this.collection = collection; + await this.props.documents.fetchRecentlyModified({ + limit: 5, + collectionId: collection.id, + }); } this.isFetching = false; @@ -93,6 +101,11 @@ class CollectionScene extends Component { {this.collection.name} Recently edited + ); } @@ -111,4 +124,4 @@ const Action = styled(Flex)` margin: 10px 0; `; -export default inject('collections', 'ui')(CollectionScene); +export default inject('collections', 'documents', 'ui')(CollectionScene); diff --git a/app/stores/CollectionsStore.js b/app/stores/CollectionsStore.js index 0a3880d2..67973f4b 100644 --- a/app/stores/CollectionsStore.js +++ b/app/stores/CollectionsStore.js @@ -96,7 +96,7 @@ class CollectionsStore { const res = await this.client.post('/collections.list'); invariant(res && res.data, 'Collection list not available'); const { data } = res; - runInAction('CollectionsStore#fetch', () => { + runInAction('CollectionsStore#fetchAll', () => { data.forEach(collection => { this.data.set(collection.id, new Collection(collection)); }); diff --git a/app/stores/DocumentsStore.js b/app/stores/DocumentsStore.js index 99235fac..4c05276b 100644 --- a/app/stores/DocumentsStore.js +++ b/app/stores/DocumentsStore.js @@ -52,6 +52,17 @@ class DocumentsStore extends BaseStore { return _.take(_.orderBy(this.data.values(), 'updatedAt', 'desc'), 5); } + recentlyEditedInCollection(collectionId: string): Array { + return _.orderBy( + _.filter( + this.data.values(), + document => document.collectionId === collectionId + ), + 'updatedAt', + 'desc' + ); + } + @computed get starred(): Array { return _.filter(this.data.values(), 'starred'); diff --git a/server/api/documents.js b/server/api/documents.js index 5e098ca8..f3f11282 100644 --- a/server/api/documents.js +++ b/server/api/documents.js @@ -15,14 +15,17 @@ const authDocumentForUser = (ctx, document) => { const router = new Router(); router.post('documents.list', auth(), pagination(), async ctx => { - let { sort = 'updatedAt', direction } = ctx.body; + let { sort = 'updatedAt', direction, collectionId } = ctx.body; if (direction !== 'ASC') direction = 'DESC'; const user = ctx.state.user; + let where = { teamId: user.teamId }; + if (collectionId) where = { ...where, atlasId: collectionId }; + const userId = user.id; const starredScope = { method: ['withStarred', userId] }; const documents = await Document.scope('defaultScope', starredScope).findAll({ - where: { teamId: user.teamId }, + where, order: [[sort, direction]], offset: ctx.state.pagination.offset, limit: ctx.state.pagination.limit, diff --git a/server/api/documents.test.js b/server/api/documents.test.js index 7d2bc37d..82380eed 100644 --- a/server/api/documents.test.js +++ b/server/api/documents.test.js @@ -34,6 +34,17 @@ describe('#documents.list', async () => { expect(body.data[1].id).toEqual(document.id); }); + it('should allow filtering by collection', async () => { + const { user, document } = await seed(); + const res = await server.post('/api/documents.list', { + body: { token: user.getJwtToken(), collectionId: document.atlasId }, + }); + const body = await res.json(); + + expect(res.status).toEqual(200); + expect(body.data.length).toEqual(2); + }); + it('should require authentication', async () => { const res = await server.post('/api/documents.list'); const body = await res.json(); diff --git a/server/presenters/document.js b/server/presenters/document.js index 575d18f3..29ddff81 100644 --- a/server/presenters/document.js +++ b/server/presenters/document.js @@ -36,6 +36,7 @@ async function present(ctx: Object, document: Document, options: ?Options) { team: document.teamId, collaborators: [], starred: !!(document.starred && document.starred.length), + collectionId: document.atlasId, collaboratorCount: undefined, collection: undefined, views: undefined,