Added event emitters and fixed document deletion
This commit is contained in:
@ -1,5 +1,6 @@
|
|||||||
// @flow
|
// @flow
|
||||||
import React from 'react';
|
import React from 'react';
|
||||||
|
import { observer } from 'mobx-react';
|
||||||
import Flex from 'components/Flex';
|
import Flex from 'components/Flex';
|
||||||
import styled from 'styled-components';
|
import styled from 'styled-components';
|
||||||
import { layout } from 'styles/constants';
|
import { layout } from 'styles/constants';
|
||||||
@ -21,7 +22,7 @@ const activeStyle = {
|
|||||||
background: '#E1E1E1',
|
background: '#E1E1E1',
|
||||||
};
|
};
|
||||||
|
|
||||||
class SidebarCollection extends React.Component {
|
@observer class SidebarCollection extends React.Component {
|
||||||
props: Props;
|
props: Props;
|
||||||
|
|
||||||
renderDocuments(documentList: Array<NavigationNode>, depth: number = 0) {
|
renderDocuments(documentList: Array<NavigationNode>, depth: number = 0) {
|
||||||
|
3
frontend/models/BaseModel.js
Normal file
3
frontend/models/BaseModel.js
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
// @flow
|
||||||
|
import BaseStore from 'stores/BaseStore';
|
||||||
|
export default BaseStore;
|
@ -3,12 +3,13 @@ import { extendObservable, action, computed, runInAction } from 'mobx';
|
|||||||
import invariant from 'invariant';
|
import invariant from 'invariant';
|
||||||
import _ from 'lodash';
|
import _ from 'lodash';
|
||||||
|
|
||||||
|
import BaseModel from 'models/BaseModel';
|
||||||
import { client } from 'utils/ApiClient';
|
import { client } from 'utils/ApiClient';
|
||||||
import stores from 'stores';
|
import stores from 'stores';
|
||||||
import ErrorsStore from 'stores/ErrorsStore';
|
import ErrorsStore from 'stores/ErrorsStore';
|
||||||
import type { NavigationNode } from 'types';
|
import type { NavigationNode } from 'types';
|
||||||
|
|
||||||
class Collection {
|
class Collection extends BaseModel {
|
||||||
isSaving: boolean = false;
|
isSaving: boolean = false;
|
||||||
hasPendingChanges: boolean = false;
|
hasPendingChanges: boolean = false;
|
||||||
errors: ErrorsStore;
|
errors: ErrorsStore;
|
||||||
@ -85,8 +86,14 @@ class Collection {
|
|||||||
}
|
}
|
||||||
|
|
||||||
constructor(collection: Object = {}) {
|
constructor(collection: Object = {}) {
|
||||||
|
super();
|
||||||
|
|
||||||
this.updateData(collection);
|
this.updateData(collection);
|
||||||
this.errors = stores.errors;
|
this.errors = stores.errors;
|
||||||
|
|
||||||
|
this.on('document.delete', (data: { collectionId: string }) => {
|
||||||
|
if (data.collectionId === this.id) this.fetch();
|
||||||
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -8,11 +8,12 @@ import ErrorsStore from 'stores/ErrorsStore';
|
|||||||
import parseTitle from '../../shared/parseTitle';
|
import parseTitle from '../../shared/parseTitle';
|
||||||
|
|
||||||
import type { User } from 'types';
|
import type { User } from 'types';
|
||||||
|
import BaseModel from './BaseModel';
|
||||||
import Collection from './Collection';
|
import Collection from './Collection';
|
||||||
|
|
||||||
const DEFAULT_TITLE = 'Untitled document';
|
const DEFAULT_TITLE = 'Untitled document';
|
||||||
|
|
||||||
class Document {
|
class Document extends BaseModel {
|
||||||
isSaving: boolean = false;
|
isSaving: boolean = false;
|
||||||
hasPendingChanges: boolean = false;
|
hasPendingChanges: boolean = false;
|
||||||
errors: ErrorsStore;
|
errors: ErrorsStore;
|
||||||
@ -109,14 +110,6 @@ class Document {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
@action delete = async () => {
|
|
||||||
try {
|
|
||||||
await client.post('/documents.delete', { id: this.id });
|
|
||||||
} catch (e) {
|
|
||||||
this.errors.add('Document failed to delete');
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
@action fetch = async () => {
|
@action fetch = async () => {
|
||||||
try {
|
try {
|
||||||
const res = await client.post('/documents.info', { id: this.id });
|
const res = await client.post('/documents.info', { id: this.id });
|
||||||
@ -177,6 +170,19 @@ class Document {
|
|||||||
return this;
|
return this;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@action delete = async () => {
|
||||||
|
try {
|
||||||
|
await client.post('/documents.delete', { id: this.id });
|
||||||
|
this.emit('document.delete', {
|
||||||
|
id: this.id,
|
||||||
|
collectionId: this.collection.id,
|
||||||
|
});
|
||||||
|
} catch (e) {
|
||||||
|
this.errors.add('Error while deleting the document');
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
};
|
||||||
|
|
||||||
updateData(data: Object = {}, dirty: boolean = false) {
|
updateData(data: Object = {}, dirty: boolean = false) {
|
||||||
if (data.text) {
|
if (data.text) {
|
||||||
const { title, emoji } = parseTitle(data.text);
|
const { title, emoji } = parseTitle(data.text);
|
||||||
@ -189,6 +195,8 @@ class Document {
|
|||||||
}
|
}
|
||||||
|
|
||||||
constructor(data?: Object = {}) {
|
constructor(data?: Object = {}) {
|
||||||
|
super();
|
||||||
|
|
||||||
this.updateData(data);
|
this.updateData(data);
|
||||||
this.errors = stores.errors;
|
this.errors = stores.errors;
|
||||||
}
|
}
|
||||||
|
@ -39,6 +39,7 @@ type Props = {
|
|||||||
|
|
||||||
if (confirm(msg)) {
|
if (confirm(msg)) {
|
||||||
this.props.document.delete();
|
this.props.document.delete();
|
||||||
|
this.props.history.push(this.props.document.collection.url);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
19
frontend/stores/BaseStore.js
Normal file
19
frontend/stores/BaseStore.js
Normal file
@ -0,0 +1,19 @@
|
|||||||
|
// @flow
|
||||||
|
import { EventEmitter } from 'fbemitter';
|
||||||
|
import _ from 'lodash';
|
||||||
|
|
||||||
|
const emitter = new EventEmitter();
|
||||||
|
window.__emitter = emitter;
|
||||||
|
|
||||||
|
class BaseStore {
|
||||||
|
emitter: EventEmitter;
|
||||||
|
on: (eventName: string, callback: Function) => void;
|
||||||
|
emit: (eventName: string, data: any) => void;
|
||||||
|
|
||||||
|
constructor() {
|
||||||
|
_.extend(this, emitter);
|
||||||
|
this.on = emitter.addListener;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export default BaseStore;
|
@ -11,6 +11,7 @@ import { client } from 'utils/ApiClient';
|
|||||||
import _ from 'lodash';
|
import _ from 'lodash';
|
||||||
import invariant from 'invariant';
|
import invariant from 'invariant';
|
||||||
|
|
||||||
|
import BaseStore from 'stores/BaseStore';
|
||||||
import stores from 'stores';
|
import stores from 'stores';
|
||||||
import Document from 'models/Document';
|
import Document from 'models/Document';
|
||||||
import ErrorsStore from 'stores/ErrorsStore';
|
import ErrorsStore from 'stores/ErrorsStore';
|
||||||
@ -22,7 +23,7 @@ type Options = {
|
|||||||
cache: CacheStore,
|
cache: CacheStore,
|
||||||
};
|
};
|
||||||
|
|
||||||
class DocumentsStore {
|
class DocumentsStore extends BaseStore {
|
||||||
@observable recentlyViewedIds: Array<string> = [];
|
@observable recentlyViewedIds: Array<string> = [];
|
||||||
@observable data: Map<string, Document> = new ObservableMap([]);
|
@observable data: Map<string, Document> = new ObservableMap([]);
|
||||||
@observable isLoaded: boolean = false;
|
@observable isLoaded: boolean = false;
|
||||||
@ -122,6 +123,8 @@ class DocumentsStore {
|
|||||||
};
|
};
|
||||||
|
|
||||||
constructor(options: Options) {
|
constructor(options: Options) {
|
||||||
|
super();
|
||||||
|
|
||||||
this.errors = stores.errors;
|
this.errors = stores.errors;
|
||||||
this.cache = options.cache;
|
this.cache = options.cache;
|
||||||
|
|
||||||
@ -131,6 +134,10 @@ class DocumentsStore {
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
this.on('document.delete', (data: { id: string }) => {
|
||||||
|
this.remove(data.id);
|
||||||
|
});
|
||||||
|
|
||||||
autorunAsync('DocumentsStore.persists', () => {
|
autorunAsync('DocumentsStore.persists', () => {
|
||||||
if (this.data.size) {
|
if (this.data.size) {
|
||||||
this.cache.setItem(
|
this.cache.setItem(
|
||||||
|
@ -97,6 +97,7 @@
|
|||||||
"eslint-plugin-react": "^6.10.3",
|
"eslint-plugin-react": "^6.10.3",
|
||||||
"exports-loader": "0.6.3",
|
"exports-loader": "0.6.3",
|
||||||
"extract-text-webpack-plugin": "1.0.1",
|
"extract-text-webpack-plugin": "1.0.1",
|
||||||
|
"fbemitter": "^2.1.1",
|
||||||
"file-loader": "0.9.0",
|
"file-loader": "0.9.0",
|
||||||
"flow-typed": "^2.1.2",
|
"flow-typed": "^2.1.2",
|
||||||
"highlight.js": "9.4.0",
|
"highlight.js": "9.4.0",
|
||||||
|
@ -3077,6 +3077,12 @@ fb-watchman@^2.0.0:
|
|||||||
dependencies:
|
dependencies:
|
||||||
bser "^2.0.0"
|
bser "^2.0.0"
|
||||||
|
|
||||||
|
fbemitter@^2.1.1:
|
||||||
|
version "2.1.1"
|
||||||
|
resolved "https://registry.yarnpkg.com/fbemitter/-/fbemitter-2.1.1.tgz#523e14fdaf5248805bb02f62efc33be703f51865"
|
||||||
|
dependencies:
|
||||||
|
fbjs "^0.8.4"
|
||||||
|
|
||||||
fbjs@0.1.0-alpha.10:
|
fbjs@0.1.0-alpha.10:
|
||||||
version "0.1.0-alpha.10"
|
version "0.1.0-alpha.10"
|
||||||
resolved "https://registry.yarnpkg.com/fbjs/-/fbjs-0.1.0-alpha.10.tgz#46e457c09cbefb51fc752a3e030e7b67fcc384c8"
|
resolved "https://registry.yarnpkg.com/fbjs/-/fbjs-0.1.0-alpha.10.tgz#46e457c09cbefb51fc752a3e030e7b67fcc384c8"
|
||||||
|
Reference in New Issue
Block a user