Manually create a new document for second collection
This commit is contained in:
parent
63288227db
commit
bbbf17c223
|
@ -26,7 +26,9 @@ class Collection {
|
|||
/* Computed */
|
||||
|
||||
@computed get entryUrl(): string {
|
||||
return this.type === 'atlas' ? this.documents[0].url : this.url;
|
||||
return this.type === 'atlas' && this.documents.length > 0
|
||||
? this.documents[0].url
|
||||
: this.url;
|
||||
}
|
||||
|
||||
/* Actions */
|
||||
|
|
|
@ -1,14 +1,20 @@
|
|||
// @flow
|
||||
import React from 'react';
|
||||
import { observable } from 'mobx';
|
||||
import { observer, inject } from 'mobx-react';
|
||||
import { Redirect } from 'react-router';
|
||||
import { Link } from 'react-router-dom';
|
||||
import _ from 'lodash';
|
||||
import styled from 'styled-components';
|
||||
import { newDocumentUrl } from 'utils/routeHelpers';
|
||||
|
||||
import CollectionsStore from 'stores/CollectionsStore';
|
||||
import CollectionStore from './CollectionStore';
|
||||
|
||||
import CenteredContent from 'components/CenteredContent';
|
||||
import LoadingListPlaceholder from 'components/LoadingListPlaceholder';
|
||||
import Button from 'components/Button';
|
||||
import Flex from 'components/Flex';
|
||||
import HelpText from 'components/HelpText';
|
||||
|
||||
type Props = {
|
||||
collections: CollectionsStore,
|
||||
|
@ -17,24 +23,66 @@ type Props = {
|
|||
|
||||
@observer class Collection extends React.Component {
|
||||
props: Props;
|
||||
store: CollectionStore;
|
||||
|
||||
constructor(props) {
|
||||
super(props);
|
||||
this.store = new CollectionStore();
|
||||
}
|
||||
collection: ?Collection;
|
||||
@observable isFetching = true;
|
||||
@observable redirectUrl;
|
||||
|
||||
componentDidMount = () => {
|
||||
const { id } = this.props.match.params;
|
||||
this.store.fetchCollection(id);
|
||||
this.fetchDocument();
|
||||
};
|
||||
|
||||
fetchDocument = async () => {
|
||||
const { collections } = this.props;
|
||||
const { id } = this.props.match.params;
|
||||
|
||||
// $FlowIssue not the correct type?
|
||||
this.collection = await collections.getById(id);
|
||||
|
||||
if (!this.collection) this.redirectUrl = '/404';
|
||||
|
||||
if (this.collection && this.collection.documents.length > 0) {
|
||||
this.redirectUrl = this.collection.documents[0].url;
|
||||
}
|
||||
this.isFetching = false;
|
||||
};
|
||||
|
||||
renderNewDocument() {
|
||||
return (
|
||||
<NewDocumentContainer auto column justify="center">
|
||||
<h1>Create a document</h1>
|
||||
<HelpText>
|
||||
Publish your first document to start building your collection.
|
||||
</HelpText>
|
||||
<Action>
|
||||
<Link
|
||||
to={// $FlowIssue stupid type
|
||||
newDocumentUrl(this.collection)}
|
||||
>
|
||||
<Button>Create new document</Button>
|
||||
</Link>
|
||||
</Action>
|
||||
</NewDocumentContainer>
|
||||
);
|
||||
}
|
||||
|
||||
render() {
|
||||
return this.store.redirectUrl
|
||||
? <Redirect to={this.store.redirectUrl} />
|
||||
: <CenteredContent>
|
||||
<LoadingListPlaceholder />
|
||||
</CenteredContent>;
|
||||
return (
|
||||
<CenteredContent>
|
||||
{this.redirectUrl && <Redirect to={this.redirectUrl} />}
|
||||
{this.isFetching
|
||||
? <LoadingListPlaceholder />
|
||||
: this.renderNewDocument()}
|
||||
</CenteredContent>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
const NewDocumentContainer = styled(Flex)`
|
||||
padding-top: 70px;
|
||||
`;
|
||||
|
||||
const Action = styled(Flex)`
|
||||
margin: 20px 0;
|
||||
`;
|
||||
|
||||
export default inject('collections')(Collection);
|
||||
|
|
|
@ -1,31 +0,0 @@
|
|||
// @flow
|
||||
import { observable, action } from 'mobx';
|
||||
import invariant from 'invariant';
|
||||
import { client } from 'utils/ApiClient';
|
||||
import { notFoundUrl } from 'utils/routeHelpers';
|
||||
|
||||
class CollectionStore {
|
||||
@observable redirectUrl: ?string;
|
||||
@observable isFetching = true;
|
||||
|
||||
/* Actions */
|
||||
|
||||
@action fetchCollection = async (id: string) => {
|
||||
this.isFetching = true;
|
||||
|
||||
try {
|
||||
const res = await client.get('/collections.info', { id });
|
||||
invariant(res && res.data, 'Data should be available');
|
||||
const { data } = res;
|
||||
|
||||
if (data.type === 'atlas') this.redirectUrl = data.documents[0].url;
|
||||
else throw new Error('TODO code up non-atlas collections');
|
||||
} catch (e) {
|
||||
console.log(e);
|
||||
this.redirectUrl = notFoundUrl();
|
||||
}
|
||||
this.isFetching = false;
|
||||
};
|
||||
}
|
||||
|
||||
export default CollectionStore;
|
|
@ -49,8 +49,25 @@ class CollectionsStore {
|
|||
}
|
||||
};
|
||||
|
||||
getById = (id: string): ?Collection => {
|
||||
return _.find(this.data, { id });
|
||||
@action getById = async (id: string): Promise<?Collection> => {
|
||||
let collection = _.find(this.data, { id });
|
||||
if (!collection) {
|
||||
try {
|
||||
const res = await this.client.post('/collections.info', {
|
||||
id,
|
||||
});
|
||||
invariant(res && res.data, 'Collection not available');
|
||||
const { data } = res;
|
||||
runInAction('CollectionsStore#getById', () => {
|
||||
collection = new Collection(data);
|
||||
this.add(collection);
|
||||
});
|
||||
} catch (e) {
|
||||
// No-op
|
||||
}
|
||||
}
|
||||
|
||||
return collection;
|
||||
};
|
||||
|
||||
@action add = (collection: Collection): void => {
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
// @flow
|
||||
import Document from 'models/Document';
|
||||
import Collection from 'models/Collection';
|
||||
|
||||
export function homeUrl(): string {
|
||||
return '/dashboard';
|
||||
|
@ -21,6 +22,10 @@ export function documentEditUrl(doc: Document): string {
|
|||
return `${doc.url}/edit`;
|
||||
}
|
||||
|
||||
export function newDocumentUrl(collection: Collection): string {
|
||||
return `${collection.url}/new`;
|
||||
}
|
||||
|
||||
export function searchUrl(query?: string): string {
|
||||
if (query) return `/search/${query}`;
|
||||
return `/search`;
|
||||
|
|
|
@ -39,19 +39,29 @@ const Collection = sequelize.define(
|
|||
collection.urlId = collection.urlId || randomstring.generate(10);
|
||||
},
|
||||
afterCreate: async collection => {
|
||||
const team = await collection.getTeam();
|
||||
const collections = await team.getCollections();
|
||||
|
||||
// Don't auto-create for journal types, yet
|
||||
if (collection.type !== 'atlas') return;
|
||||
|
||||
const document = await Document.create({
|
||||
parentDocumentId: null,
|
||||
atlasId: collection.id,
|
||||
teamId: collection.teamId,
|
||||
userId: collection.creatorId,
|
||||
lastModifiedById: collection.creatorId,
|
||||
createdById: collection.creatorId,
|
||||
title: 'Introduction',
|
||||
text: '# Introduction\n\nLets get started...',
|
||||
});
|
||||
collection.documentStructure = [document.toJSON()];
|
||||
if (collections.length === 0) {
|
||||
// Create intro document if first collection for team
|
||||
const document = await Document.create({
|
||||
parentDocumentId: null,
|
||||
atlasId: collection.id,
|
||||
teamId: collection.teamId,
|
||||
userId: collection.creatorId,
|
||||
lastModifiedById: collection.creatorId,
|
||||
createdById: collection.creatorId,
|
||||
title: 'Introduction',
|
||||
text: '# Introduction\n\nLets get started...',
|
||||
});
|
||||
collection.documentStructure = [document.toJSON()];
|
||||
} else {
|
||||
// Let user create first document
|
||||
collection.documentStructure = [];
|
||||
}
|
||||
await collection.save();
|
||||
},
|
||||
},
|
||||
|
@ -65,6 +75,9 @@ Collection.associate = models => {
|
|||
as: 'documents',
|
||||
foreignKey: 'atlasId',
|
||||
});
|
||||
Collection.belongsTo(models.Team, {
|
||||
as: 'team',
|
||||
});
|
||||
Collection.addScope('withRecentDocuments', {
|
||||
include: [
|
||||
{
|
||||
|
|
|
@ -1,3 +1,4 @@
|
|||
// @flow
|
||||
import { DataTypes, sequelize } from '../sequelize';
|
||||
import Collection from './Collection';
|
||||
|
||||
|
@ -24,7 +25,7 @@ const Team = sequelize.define(
|
|||
);
|
||||
|
||||
Team.associate = models => {
|
||||
Team.hasMany(models.Collection, { as: 'atlases' });
|
||||
Team.hasMany(models.Collection, { as: 'collections' });
|
||||
Team.hasMany(models.Document, { as: 'documents' });
|
||||
Team.hasMany(models.User, { as: 'users' });
|
||||
};
|
||||
|
|
Reference in New Issue