This repository has been archived on 2022-08-14. You can view files and clone it, but cannot push or open issues or pull requests.
outline/frontend/scenes/DocumentScene/DocumentSceneStore.js

158 lines
4.0 KiB
JavaScript
Raw Normal View History

2017-05-12 00:23:56 +00:00
// @flow
2016-08-12 12:56:39 +00:00
import _ from 'lodash';
2017-05-10 07:02:11 +00:00
import { browserHistory } from 'react-router';
2017-05-12 00:23:56 +00:00
import invariant from 'invariant';
import {
observable,
action,
computed,
runInAction,
toJS,
autorunAsync,
} from 'mobx';
2016-06-05 01:28:14 +00:00
import { client } from 'utils/ApiClient';
2017-05-12 00:23:56 +00:00
import type { Document as DocumentType, Collection } from 'types';
2016-06-05 01:28:14 +00:00
2016-07-07 07:27:11 +00:00
const DOCUMENT_PREFERENCES = 'DOCUMENT_PREFERENCES';
2017-05-12 00:23:56 +00:00
type Document = {
collection: Collection,
} & DocumentType;
class DocumentSceneStore {
2017-05-12 00:23:56 +00:00
@observable document: ?Document;
@observable collapsedNodes: string[] = [];
2016-06-05 01:28:14 +00:00
2017-05-12 00:23:56 +00:00
@observable isFetching: boolean = true;
@observable updatingContent: boolean = false;
@observable updatingStructure: boolean = false;
@observable isDeleting: boolean = false;
2016-06-05 01:28:14 +00:00
2016-06-23 05:57:39 +00:00
/* Computed */
2017-05-12 00:23:56 +00:00
@computed get isCollection(): boolean {
return !!this.document && this.document.collection.type === 'atlas';
2016-06-23 05:57:39 +00:00
}
2017-05-12 00:23:56 +00:00
@computed get collectionTree(): ?Object {
if (
2017-05-12 06:05:11 +00:00
this.document &&
this.document.collection &&
this.document.collection.type === 'atlas'
) {
const tree = this.document.collection.navigationTree;
const collapseNodes = node => {
node.collapsed = this.collapsedNodes.includes(node.id);
node.children = node.children.map(childNode => {
return collapseNodes(childNode);
});
2016-07-07 07:27:11 +00:00
2017-05-12 06:05:11 +00:00
return node;
};
2016-07-07 07:27:11 +00:00
2017-05-12 06:05:11 +00:00
return collapseNodes(toJS(tree));
}
2016-07-07 07:27:11 +00:00
}
2016-06-05 01:28:14 +00:00
/* Actions */
2017-05-12 00:23:56 +00:00
@action fetchDocument = async (
id: string,
options: { softLoad?: boolean, replaceUrl?: boolean } = {}
) => {
2016-08-27 20:48:00 +00:00
options = {
softLoad: false,
replaceUrl: true,
...options,
};
2016-08-01 16:03:17 +00:00
2016-08-27 20:48:00 +00:00
this.isFetching = !options.softLoad;
2017-04-29 21:08:15 +00:00
this.updatingContent = true;
2016-06-05 01:28:14 +00:00
try {
2017-04-29 21:08:15 +00:00
const res = await client.get('/documents.info', { id });
2017-05-12 00:23:56 +00:00
invariant(res && res.data, 'data should be available');
2016-06-05 01:28:14 +00:00
const { data } = res;
runInAction('fetchDocument', () => {
this.document = data;
2016-08-27 20:48:00 +00:00
if (options.replaceUrl) browserHistory.replace(data.url);
});
2016-06-05 01:28:14 +00:00
} catch (e) {
2017-02-10 05:18:03 +00:00
console.error('Something went wrong');
2016-06-05 01:28:14 +00:00
}
this.isFetching = false;
this.updatingContent = false;
};
2016-06-05 01:28:14 +00:00
@action deleteDocument = async () => {
2017-05-12 00:23:56 +00:00
if (!this.document) return;
2016-06-05 01:28:14 +00:00
this.isFetching = true;
try {
2016-08-01 16:03:17 +00:00
await client.post('/documents.delete', { id: this.document.id });
2017-05-12 00:23:56 +00:00
// $FlowFixMe don't be stupid
2016-08-15 19:41:51 +00:00
browserHistory.push(this.document.collection.url);
2016-06-05 01:28:14 +00:00
} catch (e) {
2017-02-10 05:18:03 +00:00
console.error('Something went wrong');
2016-06-05 01:28:14 +00:00
}
this.isFetching = false;
};
2016-06-26 05:27:44 +00:00
2017-05-12 00:23:56 +00:00
@action updateNavigationTree = async (tree: Object) => {
2016-07-07 04:44:14 +00:00
// Only update when tree changes
2017-05-12 00:23:56 +00:00
// $FlowFixMe don't be stupid
2016-08-12 12:56:39 +00:00
if (_.isEqual(toJS(tree), toJS(this.document.collection.navigationTree))) {
2016-07-07 04:44:14 +00:00
return true;
}
this.updatingStructure = true;
2016-06-26 05:27:44 +00:00
try {
2016-08-05 15:09:14 +00:00
const res = await client.post('/collections.updateNavigationTree', {
2017-05-12 00:23:56 +00:00
// $FlowFixMe don't be stupid
2016-08-05 15:09:14 +00:00
id: this.document.collection.id,
2016-08-01 16:03:17 +00:00
tree,
2016-06-26 05:27:44 +00:00
});
2017-05-12 00:23:56 +00:00
invariant(res && res.data, 'data should be available');
runInAction('updateNavigationTree', () => {
const { data } = res;
2017-05-12 00:23:56 +00:00
// $FlowFixMe don't be stupid
2016-08-05 15:09:14 +00:00
this.document.collection = data;
});
2016-06-26 05:27:44 +00:00
} catch (e) {
2017-02-10 05:18:03 +00:00
console.error('Something went wrong');
2016-06-26 05:27:44 +00:00
}
this.updatingStructure = false;
};
2016-07-07 07:27:11 +00:00
2017-05-12 00:23:56 +00:00
@action onNodeCollapse = (nodeId: string) => {
2017-02-17 07:04:52 +00:00
if (_.indexOf(this.collapsedNodes, nodeId) >= 0) {
this.collapsedNodes = _.without(this.collapsedNodes, nodeId);
2016-07-07 07:27:11 +00:00
} else {
2017-02-17 07:04:52 +00:00
this.collapsedNodes.push(nodeId);
2016-07-07 07:27:11 +00:00
}
};
2016-07-07 07:27:11 +00:00
// General
persistSettings = () => {
localStorage[DOCUMENT_PREFERENCES] = JSON.stringify({
2017-02-17 07:04:52 +00:00
collapsedNodes: toJS(this.collapsedNodes),
2016-07-07 07:27:11 +00:00
});
};
2016-07-07 07:27:11 +00:00
2017-05-12 00:23:56 +00:00
constructor(settings: { collapsedNodes: string[] }) {
2016-07-07 07:27:11 +00:00
// Rehydrate settings
2017-02-17 07:04:52 +00:00
this.collapsedNodes = settings.collapsedNodes || [];
2016-07-07 07:27:11 +00:00
// Persist settings to localStorage
// TODO: This could be done more selectively
2016-08-01 16:03:17 +00:00
autorunAsync(() => {
2016-07-07 07:27:11 +00:00
this.persistSettings();
});
}
2016-08-01 16:03:17 +00:00
}
2016-06-05 01:28:14 +00:00
export default DocumentSceneStore;
export { DOCUMENT_PREFERENCES };