From ad44c67a46adc4ee392720d60999399a80a68425 Mon Sep 17 00:00:00 2001 From: Jori Lallo Date: Thu, 3 Aug 2017 16:48:07 +0300 Subject: [PATCH] Added event emitters and fixed document deletion --- .../SidebarCollection/SidebarCollection.js | 3 ++- frontend/models/BaseModel.js | 3 +++ frontend/models/Collection.js | 9 ++++++- frontend/models/Document.js | 26 ++++++++++++------- frontend/scenes/Document/components/Menu.js | 1 + frontend/stores/BaseStore.js | 19 ++++++++++++++ frontend/stores/DocumentsStore.js | 9 ++++++- package.json | 1 + yarn.lock | 6 +++++ 9 files changed, 65 insertions(+), 12 deletions(-) create mode 100644 frontend/models/BaseModel.js create mode 100644 frontend/stores/BaseStore.js diff --git a/frontend/components/Layout/components/SidebarCollection/SidebarCollection.js b/frontend/components/Layout/components/SidebarCollection/SidebarCollection.js index 9d02cd85..5f46528e 100644 --- a/frontend/components/Layout/components/SidebarCollection/SidebarCollection.js +++ b/frontend/components/Layout/components/SidebarCollection/SidebarCollection.js @@ -1,5 +1,6 @@ // @flow import React from 'react'; +import { observer } from 'mobx-react'; import Flex from 'components/Flex'; import styled from 'styled-components'; import { layout } from 'styles/constants'; @@ -21,7 +22,7 @@ const activeStyle = { background: '#E1E1E1', }; -class SidebarCollection extends React.Component { +@observer class SidebarCollection extends React.Component { props: Props; renderDocuments(documentList: Array, depth: number = 0) { diff --git a/frontend/models/BaseModel.js b/frontend/models/BaseModel.js new file mode 100644 index 00000000..11cb5f2d --- /dev/null +++ b/frontend/models/BaseModel.js @@ -0,0 +1,3 @@ +// @flow +import BaseStore from 'stores/BaseStore'; +export default BaseStore; diff --git a/frontend/models/Collection.js b/frontend/models/Collection.js index 66c207ca..f6d021de 100644 --- a/frontend/models/Collection.js +++ b/frontend/models/Collection.js @@ -3,12 +3,13 @@ import { extendObservable, action, computed, runInAction } from 'mobx'; import invariant from 'invariant'; import _ from 'lodash'; +import BaseModel from 'models/BaseModel'; import { client } from 'utils/ApiClient'; import stores from 'stores'; import ErrorsStore from 'stores/ErrorsStore'; import type { NavigationNode } from 'types'; -class Collection { +class Collection extends BaseModel { isSaving: boolean = false; hasPendingChanges: boolean = false; errors: ErrorsStore; @@ -85,8 +86,14 @@ class Collection { } constructor(collection: Object = {}) { + super(); + this.updateData(collection); this.errors = stores.errors; + + this.on('document.delete', (data: { collectionId: string }) => { + if (data.collectionId === this.id) this.fetch(); + }); } } diff --git a/frontend/models/Document.js b/frontend/models/Document.js index c13341f2..ae30a5b3 100644 --- a/frontend/models/Document.js +++ b/frontend/models/Document.js @@ -8,11 +8,12 @@ import ErrorsStore from 'stores/ErrorsStore'; import parseTitle from '../../shared/parseTitle'; import type { User } from 'types'; +import BaseModel from './BaseModel'; import Collection from './Collection'; const DEFAULT_TITLE = 'Untitled document'; -class Document { +class Document extends BaseModel { isSaving: boolean = false; hasPendingChanges: boolean = false; 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 () => { try { const res = await client.post('/documents.info', { id: this.id }); @@ -177,6 +170,19 @@ class Document { 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) { if (data.text) { const { title, emoji } = parseTitle(data.text); @@ -189,6 +195,8 @@ class Document { } constructor(data?: Object = {}) { + super(); + this.updateData(data); this.errors = stores.errors; } diff --git a/frontend/scenes/Document/components/Menu.js b/frontend/scenes/Document/components/Menu.js index 5157d905..9d3cf958 100644 --- a/frontend/scenes/Document/components/Menu.js +++ b/frontend/scenes/Document/components/Menu.js @@ -39,6 +39,7 @@ type Props = { if (confirm(msg)) { this.props.document.delete(); + this.props.history.push(this.props.document.collection.url); } }; diff --git a/frontend/stores/BaseStore.js b/frontend/stores/BaseStore.js new file mode 100644 index 00000000..80357691 --- /dev/null +++ b/frontend/stores/BaseStore.js @@ -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; diff --git a/frontend/stores/DocumentsStore.js b/frontend/stores/DocumentsStore.js index 44151ba2..d79ce66c 100644 --- a/frontend/stores/DocumentsStore.js +++ b/frontend/stores/DocumentsStore.js @@ -11,6 +11,7 @@ import { client } from 'utils/ApiClient'; import _ from 'lodash'; import invariant from 'invariant'; +import BaseStore from 'stores/BaseStore'; import stores from 'stores'; import Document from 'models/Document'; import ErrorsStore from 'stores/ErrorsStore'; @@ -22,7 +23,7 @@ type Options = { cache: CacheStore, }; -class DocumentsStore { +class DocumentsStore extends BaseStore { @observable recentlyViewedIds: Array = []; @observable data: Map = new ObservableMap([]); @observable isLoaded: boolean = false; @@ -122,6 +123,8 @@ class DocumentsStore { }; constructor(options: Options) { + super(); + this.errors = stores.errors; this.cache = options.cache; @@ -131,6 +134,10 @@ class DocumentsStore { } }); + this.on('document.delete', (data: { id: string }) => { + this.remove(data.id); + }); + autorunAsync('DocumentsStore.persists', () => { if (this.data.size) { this.cache.setItem( diff --git a/package.json b/package.json index 2384681f..197f02b7 100644 --- a/package.json +++ b/package.json @@ -97,6 +97,7 @@ "eslint-plugin-react": "^6.10.3", "exports-loader": "0.6.3", "extract-text-webpack-plugin": "1.0.1", + "fbemitter": "^2.1.1", "file-loader": "0.9.0", "flow-typed": "^2.1.2", "highlight.js": "9.4.0", diff --git a/yarn.lock b/yarn.lock index 67384488..02cbb23b 100644 --- a/yarn.lock +++ b/yarn.lock @@ -3077,6 +3077,12 @@ fb-watchman@^2.0.0: dependencies: 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: version "0.1.0-alpha.10" resolved "https://registry.yarnpkg.com/fbjs/-/fbjs-0.1.0-alpha.10.tgz#46e457c09cbefb51fc752a3e030e7b67fcc384c8"