diff --git a/.babelrc b/.babelrc index 2963edac602a..cfcb01298eae 100644 --- a/.babelrc +++ b/.babelrc @@ -1,5 +1,8 @@ { - "presets": ["react", "env"], + "presets": [ + "react", + "env" + ], "plugins": [ "lodash", "transform-decorators-legacy", @@ -10,7 +13,9 @@ ], "env": { "development": { - "presets": ["react-hmre"] + "presets": [ + "react-hmre" + ] } } -} +} \ No newline at end of file diff --git a/.eslintrc b/.eslintrc index 2f3cc99a57ff..e36381a443ff 100644 --- a/.eslintrc +++ b/.eslintrc @@ -1,6 +1,10 @@ { "parser": "babel-eslint", - "extends": ["react-app", "plugin:import/errors", "plugin:import/warnings"], + "extends": [ + "react-app", + "plugin:import/errors", + "plugin:import/warnings" + ], "plugins": [ "prettier" ], @@ -10,23 +14,25 @@ // does more harm than good. "no-mixed-operators": "off", // Enforce that code is formatted with prettier. - "prettier/prettier": ["error", {"trailingComma": "es5", "singleQuote": true}] - }, - "settings" : { - "import/resolver": { - "webpack": { - "config": "webpack.config.js" + "prettier/prettier": [ + "error", + { + "trailingComma": "es5", + "singleQuote": true } - } + ] + }, + "settings": { + "import/resolver": "webpack" }, "env": { - "jest": true, + "jest": true }, "globals": { - __DEV__: true, - SLACK_KEY: true, - SLACK_REDIRECT_URI: true, - DEPLOYMENT: true, - afterAll: true - }, -} + "__DEV__": true, + "SLACK_KEY": true, + "SLACK_REDIRECT_URI": true, + "DEPLOYMENT": true, + "afterAll": true + } +} \ No newline at end of file diff --git a/.flowconfig b/.flowconfig index bec59bf68d0a..3e6536de22ad 100644 --- a/.flowconfig +++ b/.flowconfig @@ -4,9 +4,18 @@ [libs] [options] +emoji=true + +module.system.node.resolve_dirname=node_modules +module.system.node.resolve_dirname=frontend + +module.name_mapper='^\(.*\)\.s?css$' -> 'empty/object' +module.file_ext=.scss + esproposal.decorators=ignore esproposal.class_static_fields=enable esproposal.class_instance_fields=enable unsafe.enable_getters_and_setters=true -module.name_mapper='^\(.*\)\.s?css$' -> 'empty/object' -module.file_ext=.scss + +suppress_comment=\\(.\\|\n\\)*\\$FlowFixMe +suppress_comment=\\(.\\|\n\\)*\\$FlowIssue diff --git a/frontend/components/Document/Document.js b/frontend/components/Document/Document.js index 13649a395284..fbe505d88721 100644 --- a/frontend/components/Document/Document.js +++ b/frontend/components/Document/Document.js @@ -2,7 +2,7 @@ import React from 'react'; import { toJS } from 'mobx'; import { observer } from 'mobx-react'; -import type { Document as DocumentType } from '../../../types'; +import type { Document as DocumentType } from 'types'; import PublishingInfo from '../PublishingInfo'; import styles from './Document.scss'; import DocumentHtml from './components/DocumentHtml'; diff --git a/frontend/components/DocumentList/DocumentList.js b/frontend/components/DocumentList/DocumentList.js index e914711c70ab..583c0c66237d 100644 --- a/frontend/components/DocumentList/DocumentList.js +++ b/frontend/components/DocumentList/DocumentList.js @@ -1,6 +1,6 @@ // @flow import React from 'react'; -import type { Document } from '../../../types'; +import type { Document } from 'types'; import DocumentPreview from 'components/DocumentPreview'; import Divider from 'components/Divider'; diff --git a/frontend/components/SlackAuthLink/SlackAuthLink.js b/frontend/components/SlackAuthLink/SlackAuthLink.js index 9b6d8edb192a..c5edb4f307f2 100644 --- a/frontend/components/SlackAuthLink/SlackAuthLink.js +++ b/frontend/components/SlackAuthLink/SlackAuthLink.js @@ -1,7 +1,7 @@ // @flow import React from 'react'; import { observer, inject } from 'mobx-react'; -import type { User } from '../../../types'; +import type { User } from 'types'; @inject('user') @observer diff --git a/frontend/scenes/Dashboard/Dashboard.js b/frontend/scenes/Dashboard/Dashboard.js index d0e3ab025691..0a3af592fa71 100644 --- a/frontend/scenes/Dashboard/Dashboard.js +++ b/frontend/scenes/Dashboard/Dashboard.js @@ -1,25 +1,29 @@ +// @flow import React from 'react'; import { observer, inject } from 'mobx-react'; import { withRouter } from 'react-router'; +import { Flex } from 'reflexbox'; import DashboardStore from './DashboardStore'; -import { Flex } from 'reflexbox'; import Layout from 'components/Layout'; import AtlasPreview from 'components/AtlasPreview'; import AtlasPreviewLoading from 'components/AtlasPreviewLoading'; import CenteredContent from 'components/CenteredContent'; +type Props = { + user: Object, + router: Object, +}; + @withRouter @inject('user') @observer class Dashboard extends React.Component { - static propTypes = { - user: React.PropTypes.object.isRequired, - router: React.PropTypes.object.isRequired, - }; + props: Props; + store: DashboardStore; - constructor(props) { + constructor(props: Props) { super(props); this.store = new DashboardStore({ diff --git a/frontend/scenes/Dashboard/DashboardStore.js b/frontend/scenes/Dashboard/DashboardStore.js index aaf676014f8b..474816a4bd0e 100644 --- a/frontend/scenes/Dashboard/DashboardStore.js +++ b/frontend/scenes/Dashboard/DashboardStore.js @@ -1,11 +1,20 @@ +// @flow import { observable, action, runInAction } from 'mobx'; import { client } from 'utils/ApiClient'; +import type { Pagination, Collection } from 'types'; + +type Options = { + team: Object, + router: Object, +}; class DashboardStore { - @observable collections; - @observable pagination; + team: Object; + router: Object; + @observable collections: Array; + @observable pagination: Pagination; - @observable isFetching = true; + @observable isFetching: boolean = true; /* Actions */ @@ -19,18 +28,13 @@ class DashboardStore { this.collections = data; this.pagination = pagination; }); - - // If only one collection, visit it automatically - if (this.collections.length === 1) { - this.router.push(this.collections[0].url); - } } catch (e) { console.error('Something went wrong'); } this.isFetching = false; }; - constructor(options) { + constructor(options: Options) { this.team = options.team; this.router = options.router; this.fetchCollections(); diff --git a/frontend/scenes/Settings/Settings.js b/frontend/scenes/Settings/Settings.js index 31c4b6e00763..a1a19500494c 100644 --- a/frontend/scenes/Settings/Settings.js +++ b/frontend/scenes/Settings/Settings.js @@ -3,15 +3,15 @@ import React from 'react'; import { observer } from 'mobx-react'; import styled from 'styled-components'; import { Flex } from 'reflexbox'; -import Layout, { Title } from 'components/Layout'; -import CenteredContent from 'components/CenteredContent'; -import SlackAuthLink from 'components/SlackAuthLink'; -import ApiKeyRow from './components/ApiKeyRow'; +import ApiKeyRow from './components/ApiKeyRow'; import styles from './Settings.scss'; - import SettingsStore from './SettingsStore'; +import Layout, { Title } from 'components/Layout'; +import CenteredContent from 'components/CenteredContent'; +import SlackAuthLink from 'components/SlackAuthLink'; + @observer class Settings extends React.Component { store = SettingsStore; diff --git a/types.js b/frontend/types/index.js similarity index 77% rename from types.js rename to frontend/types/index.js index 7fea471e07a7..3ac30e743a76 100644 --- a/types.js +++ b/frontend/types/index.js @@ -1,3 +1,4 @@ +// @flow export type User = { avatarUrl: string, id: string, @@ -7,10 +8,10 @@ export type User = { export type Collection = { createdAt: string, - description: string, + description: ?string, id: string, name: string, - type: string, + type: 'atlas' | 'journal', updatedAt: string, url: string, }; @@ -30,3 +31,9 @@ export type Document = { updatedBy: string, url: string, }; + +export type Pagination = { + limit: number, + nextPath: string, + offset: number, +}; diff --git a/package.json b/package.json index 3d024f19fdb4..72296a92d769 100644 --- a/package.json +++ b/package.json @@ -9,7 +9,9 @@ "build": "npm run clean && npm run build:webpack", "start": "node index.js", "dev": "cross-env NODE_ENV=development DEBUG=sql,cache,presenters ./node_modules/.bin/nodemon --watch server index.js", - "lint": "eslint frontend", + "lint": "npm run lint:js && npm run lint:flow", + "lint:js": "eslint frontend", + "lint:flow": "flow check", "deploy": "git push heroku master", "heroku-postbuild": "npm run build && npm run sequelize db:migrate", "sequelize": "./node_modules/.bin/sequelize", @@ -92,6 +94,7 @@ "exports-loader": "0.6.3", "extract-text-webpack-plugin": "1.0.1", "file-loader": "0.9.0", + "flow": "^0.2.3", "highlight.js": "9.4.0", "history": "3.0.0", "html-webpack-plugin": "2.17.0", @@ -174,4 +177,4 @@ "react-addons-test-utils": "^15.3.1", "react-test-renderer": "^15.3.1" } -} +} \ No newline at end of file diff --git a/yarn.lock b/yarn.lock index 684c2631b5fc..36ad258ba0dc 100644 --- a/yarn.lock +++ b/yarn.lock @@ -3036,6 +3036,10 @@ flow-parser@0.43.0: version "0.43.0" resolved "https://registry.yarnpkg.com/flow-parser/-/flow-parser-0.43.0.tgz#e2b8eb1ac83dd53f7b6b04a7c35b6a52c33479b7" +flow@^0.2.3: + version "0.2.3" + resolved "https://registry.yarnpkg.com/flow/-/flow-0.2.3.tgz#f8da65efa249127ec99376a28896572a9795d1af" + for-in@^0.1.5: version "0.1.6" resolved "https://registry.yarnpkg.com/for-in/-/for-in-0.1.6.tgz#c9f96e89bfad18a545af5ec3ed352a1d9e5b4dc8"