Working recently edited list
This commit is contained in:
@ -20,6 +20,7 @@ class Document extends BaseModel {
|
|||||||
|
|
||||||
collaborators: Array<User>;
|
collaborators: Array<User>;
|
||||||
collection: $Shape<Collection>;
|
collection: $Shape<Collection>;
|
||||||
|
collectionId: string;
|
||||||
firstViewedAt: ?string;
|
firstViewedAt: ?string;
|
||||||
lastViewedAt: ?string;
|
lastViewedAt: ?string;
|
||||||
modifiedSinceViewed: ?boolean;
|
modifiedSinceViewed: ?boolean;
|
||||||
|
@ -7,6 +7,7 @@ import styled from 'styled-components';
|
|||||||
import { newDocumentUrl } from 'utils/routeHelpers';
|
import { newDocumentUrl } from 'utils/routeHelpers';
|
||||||
|
|
||||||
import CollectionsStore from 'stores/CollectionsStore';
|
import CollectionsStore from 'stores/CollectionsStore';
|
||||||
|
import DocumentsStore from 'stores/DocumentsStore';
|
||||||
import UiStore from 'stores/UiStore';
|
import UiStore from 'stores/UiStore';
|
||||||
import Collection from 'models/Collection';
|
import Collection from 'models/Collection';
|
||||||
|
|
||||||
@ -16,12 +17,14 @@ import CollectionIcon from 'components/Icon/CollectionIcon';
|
|||||||
import LoadingListPlaceholder from 'components/LoadingListPlaceholder';
|
import LoadingListPlaceholder from 'components/LoadingListPlaceholder';
|
||||||
import Button from 'components/Button';
|
import Button from 'components/Button';
|
||||||
import HelpText from 'components/HelpText';
|
import HelpText from 'components/HelpText';
|
||||||
|
import DocumentList from 'components/DocumentList';
|
||||||
import Subheading from 'components/Subheading';
|
import Subheading from 'components/Subheading';
|
||||||
import PageTitle from 'components/PageTitle';
|
import PageTitle from 'components/PageTitle';
|
||||||
import Flex from 'shared/components/Flex';
|
import Flex from 'shared/components/Flex';
|
||||||
|
|
||||||
type Props = {
|
type Props = {
|
||||||
ui: UiStore,
|
ui: UiStore,
|
||||||
|
documents: DocumentsStore,
|
||||||
collections: CollectionsStore,
|
collections: CollectionsStore,
|
||||||
match: Object,
|
match: Object,
|
||||||
};
|
};
|
||||||
@ -32,23 +35,28 @@ class CollectionScene extends Component {
|
|||||||
@observable collection: ?Collection;
|
@observable collection: ?Collection;
|
||||||
@observable isFetching: boolean = true;
|
@observable isFetching: boolean = true;
|
||||||
|
|
||||||
componentDidMount = () => {
|
componentDidMount() {
|
||||||
this.fetchCollection(this.props.match.params.id);
|
this.loadContent(this.props.match.params.id);
|
||||||
};
|
}
|
||||||
|
|
||||||
componentWillReceiveProps(nextProps) {
|
componentWillReceiveProps(nextProps) {
|
||||||
if (nextProps.match.params.id !== this.props.match.params.id) {
|
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 { collections } = this.props;
|
||||||
|
|
||||||
const collection = await collections.fetch(id);
|
const collection = await collections.fetch(id);
|
||||||
|
|
||||||
if (collection) {
|
if (collection) {
|
||||||
this.props.ui.setActiveCollection(collection);
|
this.props.ui.setActiveCollection(collection);
|
||||||
this.collection = collection;
|
this.collection = collection;
|
||||||
|
await this.props.documents.fetchRecentlyModified({
|
||||||
|
limit: 5,
|
||||||
|
collectionId: collection.id,
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
this.isFetching = false;
|
this.isFetching = false;
|
||||||
@ -93,6 +101,11 @@ class CollectionScene extends Component {
|
|||||||
{this.collection.name}
|
{this.collection.name}
|
||||||
</Heading>
|
</Heading>
|
||||||
<Subheading>Recently edited</Subheading>
|
<Subheading>Recently edited</Subheading>
|
||||||
|
<DocumentList
|
||||||
|
documents={this.props.documents.recentlyEditedInCollection(
|
||||||
|
this.collection.id
|
||||||
|
)}
|
||||||
|
/>
|
||||||
</CenteredContent>
|
</CenteredContent>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
@ -111,4 +124,4 @@ const Action = styled(Flex)`
|
|||||||
margin: 10px 0;
|
margin: 10px 0;
|
||||||
`;
|
`;
|
||||||
|
|
||||||
export default inject('collections', 'ui')(CollectionScene);
|
export default inject('collections', 'documents', 'ui')(CollectionScene);
|
||||||
|
@ -96,7 +96,7 @@ class CollectionsStore {
|
|||||||
const res = await this.client.post('/collections.list');
|
const res = await this.client.post('/collections.list');
|
||||||
invariant(res && res.data, 'Collection list not available');
|
invariant(res && res.data, 'Collection list not available');
|
||||||
const { data } = res;
|
const { data } = res;
|
||||||
runInAction('CollectionsStore#fetch', () => {
|
runInAction('CollectionsStore#fetchAll', () => {
|
||||||
data.forEach(collection => {
|
data.forEach(collection => {
|
||||||
this.data.set(collection.id, new Collection(collection));
|
this.data.set(collection.id, new Collection(collection));
|
||||||
});
|
});
|
||||||
|
@ -52,6 +52,17 @@ class DocumentsStore extends BaseStore {
|
|||||||
return _.take(_.orderBy(this.data.values(), 'updatedAt', 'desc'), 5);
|
return _.take(_.orderBy(this.data.values(), 'updatedAt', 'desc'), 5);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
recentlyEditedInCollection(collectionId: string): Array<Document> {
|
||||||
|
return _.orderBy(
|
||||||
|
_.filter(
|
||||||
|
this.data.values(),
|
||||||
|
document => document.collectionId === collectionId
|
||||||
|
),
|
||||||
|
'updatedAt',
|
||||||
|
'desc'
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
@computed
|
@computed
|
||||||
get starred(): Array<Document> {
|
get starred(): Array<Document> {
|
||||||
return _.filter(this.data.values(), 'starred');
|
return _.filter(this.data.values(), 'starred');
|
||||||
|
@ -15,14 +15,17 @@ const authDocumentForUser = (ctx, document) => {
|
|||||||
const router = new Router();
|
const router = new Router();
|
||||||
|
|
||||||
router.post('documents.list', auth(), pagination(), async ctx => {
|
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';
|
if (direction !== 'ASC') direction = 'DESC';
|
||||||
|
|
||||||
const user = ctx.state.user;
|
const user = ctx.state.user;
|
||||||
|
let where = { teamId: user.teamId };
|
||||||
|
if (collectionId) where = { ...where, atlasId: collectionId };
|
||||||
|
|
||||||
const userId = user.id;
|
const userId = user.id;
|
||||||
const starredScope = { method: ['withStarred', userId] };
|
const starredScope = { method: ['withStarred', userId] };
|
||||||
const documents = await Document.scope('defaultScope', starredScope).findAll({
|
const documents = await Document.scope('defaultScope', starredScope).findAll({
|
||||||
where: { teamId: user.teamId },
|
where,
|
||||||
order: [[sort, direction]],
|
order: [[sort, direction]],
|
||||||
offset: ctx.state.pagination.offset,
|
offset: ctx.state.pagination.offset,
|
||||||
limit: ctx.state.pagination.limit,
|
limit: ctx.state.pagination.limit,
|
||||||
|
@ -34,6 +34,17 @@ describe('#documents.list', async () => {
|
|||||||
expect(body.data[1].id).toEqual(document.id);
|
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 () => {
|
it('should require authentication', async () => {
|
||||||
const res = await server.post('/api/documents.list');
|
const res = await server.post('/api/documents.list');
|
||||||
const body = await res.json();
|
const body = await res.json();
|
||||||
|
@ -36,6 +36,7 @@ async function present(ctx: Object, document: Document, options: ?Options) {
|
|||||||
team: document.teamId,
|
team: document.teamId,
|
||||||
collaborators: [],
|
collaborators: [],
|
||||||
starred: !!(document.starred && document.starred.length),
|
starred: !!(document.starred && document.starred.length),
|
||||||
|
collectionId: document.atlasId,
|
||||||
collaboratorCount: undefined,
|
collaboratorCount: undefined,
|
||||||
collection: undefined,
|
collection: undefined,
|
||||||
views: undefined,
|
views: undefined,
|
||||||
|
Reference in New Issue
Block a user