From bdb7c46874477a177854e8baecd71c3d92348917 Mon Sep 17 00:00:00 2001 From: Tom Moor Date: Sun, 3 Sep 2017 15:45:25 -0700 Subject: [PATCH 1/6] Remove UserStore --- frontend/components/Layout/Layout.js | 7 +++--- frontend/index.js | 9 ++++---- frontend/stores/AuthStore.js | 12 ----------- frontend/stores/UserStore.js | 32 ---------------------------- 4 files changed, 7 insertions(+), 53 deletions(-) delete mode 100644 frontend/stores/UserStore.js diff --git a/frontend/components/Layout/Layout.js b/frontend/components/Layout/Layout.js index 9679eb833..284383a2e 100644 --- a/frontend/components/Layout/Layout.js +++ b/frontend/components/Layout/Layout.js @@ -27,7 +27,6 @@ import SidebarCollection from './components/SidebarCollection'; import SidebarCollectionList from './components/SidebarCollectionList'; import SidebarLink from './components/SidebarLink'; -import UserStore from 'stores/UserStore'; import AuthStore from 'stores/AuthStore'; import UiStore from 'stores/UiStore'; import CollectionsStore from 'stores/CollectionsStore'; @@ -40,7 +39,6 @@ type Props = { children?: ?React.Element, actions?: ?React.Element, title?: ?React.Element, - user: UserStore, auth: AuthStore, ui: UiStore, search: ?boolean, @@ -108,7 +106,8 @@ type Props = { }; render() { - const { user, auth, documents, collections, history, ui } = this.props; + const { auth, documents, collections, history, ui } = this.props; + const { user } = auth; return ( @@ -134,7 +133,7 @@ type Props = { Atlas - }> + }> Settings diff --git a/frontend/index.js b/frontend/index.js index d47f3774f..b783b4e76 100644 --- a/frontend/index.js +++ b/frontend/index.js @@ -51,23 +51,22 @@ type AuthProps = { }; const Auth = ({ children }: AuthProps) => { - if (stores.auth.authenticated && stores.auth.team) { + if (stores.auth.authenticated && stores.auth.team && stores.auth.user) { // Only initialize stores once. Kept in global scope // because otherwise they will get overriden on route // change if (!authenticatedStores) { // Stores for authenticated user - const user = stores.auth.getUserStore(); - const cache = new CacheStore(user.user.id); + const { user, team } = stores.auth; + const cache = new CacheStore(user.id); authenticatedStores = { - user, documents: new DocumentsStore({ ui: stores.ui, cache, }), collections: new CollectionsStore({ ui: stores.ui, - teamId: user.team.id, + teamId: team.id, cache, }), }; diff --git a/frontend/stores/AuthStore.js b/frontend/stores/AuthStore.js index dcc879c41..f5b77ecbe 100644 --- a/frontend/stores/AuthStore.js +++ b/frontend/stores/AuthStore.js @@ -2,7 +2,6 @@ import { observable, action, computed, autorunAsync } from 'mobx'; import invariant from 'invariant'; import { client } from 'utils/ApiClient'; -import UserStore from 'stores/UserStore'; import type { User, Team } from 'types'; const AUTH_STORE = 'AUTH_STORE'; @@ -72,17 +71,6 @@ class AuthStore { }; }; - getUserStore(): UserStore { - invariant( - this.user && this.team, - 'Tried to create a user store without data' - ); - return new UserStore({ - user: this.user, - team: this.team, - }); - } - constructor() { // Rehydrate const data = JSON.parse(localStorage.getItem(AUTH_STORE) || '{}'); diff --git a/frontend/stores/UserStore.js b/frontend/stores/UserStore.js deleted file mode 100644 index 7d368c934..000000000 --- a/frontend/stores/UserStore.js +++ /dev/null @@ -1,32 +0,0 @@ -// @flow -import { observable, computed } from 'mobx'; -import type { User, Team } from 'types'; - -type Options = { - user: User, - team: Team, -}; - -class UserStore { - @observable user: User; - @observable team: Team; - - @observable isLoading: boolean = false; - - /* Computed */ - - @computed get asJson(): string { - return JSON.stringify({ - user: this.user, - team: this.team, - }); - } - - constructor(options: Options) { - // Rehydrate - this.user = options.user; - this.team = options.team; - } -} - -export default UserStore; From 432b7afede344baf33ccecaf13d96450927d2ed1 Mon Sep 17 00:00:00 2001 From: Tom Moor Date: Sun, 3 Sep 2017 17:08:56 -0700 Subject: [PATCH 2/6] Refactor Slack signin codE --- frontend/components/Layout/Layout.js | 6 ++- server/api/auth.js | 59 +++++----------------------- server/slack.js | 34 ++++++++++++++++ 3 files changed, 48 insertions(+), 51 deletions(-) create mode 100644 server/slack.js diff --git a/frontend/components/Layout/Layout.js b/frontend/components/Layout/Layout.js index 284383a2e..b42b7426a 100644 --- a/frontend/components/Layout/Layout.js +++ b/frontend/components/Layout/Layout.js @@ -107,7 +107,7 @@ type Props = { render() { const { auth, documents, collections, history, ui } = this.props; - const { user } = auth; + const { user, team } = auth; return ( @@ -128,10 +128,12 @@ type Props = { {auth.authenticated && user && + team &&
- Atlas + {team.name} + {user.username} }> diff --git a/server/api/auth.js b/server/api/auth.js index 811055cf5..35ae88c14 100644 --- a/server/api/auth.js +++ b/server/api/auth.js @@ -1,11 +1,9 @@ // @flow import Router from 'koa-router'; -import apiError, { httpErrors } from '../errors'; -import fetch from 'isomorphic-fetch'; -import querystring from 'querystring'; - +import apiError from '../errors'; import { presentUser, presentTeam } from '../presenters'; import { User, Team } from '../models'; +import * as Slack from '../slack'; const router = new Router(); @@ -88,24 +86,7 @@ router.post('auth.slack', async ctx => { const { code } = ctx.body; ctx.assertPresent(code, 'code is required'); - const body = { - client_id: process.env.SLACK_KEY, - client_secret: process.env.SLACK_SECRET, - redirect_uri: `${process.env.URL || ''}/auth/slack`, - code, - }; - - let data; - try { - const response = await fetch( - `https://slack.com/api/oauth.access?${querystring.stringify(body)}` - ); - data = await response.json(); - } catch (e) { - throw httpErrors.BadRequest(); - } - - if (!data.ok) throw httpErrors.BadRequest(data.error); + const data = await Slack.oauthAccess(code); // Temp to block const allowedSlackDomains = (process.env.ALLOWED_SLACK_DOMAINS || '') @@ -118,22 +99,20 @@ router.post('auth.slack', async ctx => { ); } - // User let user = await User.findOne({ where: { slackId: data.user.id } }); - - // Team let team = await Team.findOne({ where: { slackId: data.team.id } }); const teamExisted = !!team; - if (!team) { + + if (team) { + team.name = data.team.name; + team.slackData = data.team; + await team.save(); + } else { team = await Team.create({ name: data.team.name, slackId: data.team.id, slackData: data.team, }); - } else { - team.name = data.team.name; - team.slackData = data.team; - team = await team.save(); } if (user) { @@ -143,7 +122,6 @@ router.post('auth.slack', async ctx => { } else { user = await User.create({ slackId: data.user.id, - username: data.user.name, name: data.user.name, email: data.user.email, teamId: team.id, @@ -169,24 +147,7 @@ router.post('auth.slackCommands', async ctx => { const { code } = ctx.body; ctx.assertPresent(code, 'code is required'); - const body = { - client_id: process.env.SLACK_KEY, - client_secret: process.env.SLACK_SECRET, - redirect_uri: `${process.env.URL || ''}/auth/slack/commands`, - code, - }; - - let data; - try { - const response = await fetch( - `https://slack.com/api/oauth.access?${querystring.stringify(body)}` - ); - data = await response.json(); - } catch (e) { - throw httpErrors.BadRequest(); - } - - if (!data.ok) throw httpErrors.BadRequest(data.error); + await Slack.oauthAccess(code, `${process.env.URL || ''}/auth/slack/commands`); }); export default router; diff --git a/server/slack.js b/server/slack.js new file mode 100644 index 000000000..62bb75eb5 --- /dev/null +++ b/server/slack.js @@ -0,0 +1,34 @@ +// @flow +import fetch from 'isomorphic-fetch'; +import querystring from 'querystring'; +import { httpErrors } from './errors'; + +const SLACK_API_URL = 'https://slack.com/api'; + +export async function request(endpoint: string, body: Object) { + let data; + try { + const response = await fetch( + `${SLACK_API_URL}/${endpoint}?${querystring.stringify(body)}` + ); + data = await response.json(); + } catch (e) { + throw httpErrors.BadRequest(); + } + console.log('DATA', data); + if (!data.ok) throw httpErrors.BadRequest(data.error); + + return data; +} + +export async function oauthAccess( + code: string, + redirect_uri: string = `${process.env.URL || ''}/auth/slack` +) { + return request('oauth.access', { + client_id: process.env.SLACK_KEY, + client_secret: process.env.SLACK_SECRET, + redirect_uri: `${process.env.URL || ''}/auth/slack`, + code, + }); +} From 1b52cb6c19d6acc57c64f990303fabd5d8d56339 Mon Sep 17 00:00:00 2001 From: Tom Moor Date: Sun, 3 Sep 2017 17:27:12 -0700 Subject: [PATCH 3/6] Refactor --- frontend/components/Layout/Layout.js | 37 ++++------------ .../Layout/components/HeaderBlock.js | 42 +++++++++++++++++++ 2 files changed, 51 insertions(+), 28 deletions(-) create mode 100644 frontend/components/Layout/components/HeaderBlock.js diff --git a/frontend/components/Layout/Layout.js b/frontend/components/Layout/Layout.js index b42b7426a..87ff7dd91 100644 --- a/frontend/components/Layout/Layout.js +++ b/frontend/components/Layout/Layout.js @@ -10,11 +10,11 @@ import keydown from 'react-keydown'; import Flex from 'components/Flex'; import { color, layout } from 'styles/constants'; import { documentEditUrl, homeUrl, searchUrl } from 'utils/routeHelpers'; - import { DropdownMenu, DropdownMenuItem } from 'components/DropdownMenu'; + +import Avatar from 'components/Avatar'; import { LoadingIndicatorBar } from 'components/LoadingIndicator'; import Scrollable from 'components/Scrollable'; -import Avatar from 'components/Avatar'; import Modal from 'components/Modal'; import AddIcon from 'components/Icon/AddIcon'; import MoreIcon from 'components/Icon/MoreIcon'; @@ -26,6 +26,7 @@ import Settings from 'scenes/Settings'; import SidebarCollection from './components/SidebarCollection'; import SidebarCollectionList from './components/SidebarCollectionList'; import SidebarLink from './components/SidebarLink'; +import HeaderBlock from './components/HeaderBlock'; import AuthStore from 'stores/AuthStore'; import UiStore from 'stores/UiStore'; @@ -130,11 +131,7 @@ type Props = { user && team && -
- - {team.name} - {user.username} - + }> Settings @@ -149,8 +146,7 @@ type Props = { Logout -
- + @@ -251,19 +247,6 @@ const Container = styled(Flex)` height: 100%; `; -const LogoLink = styled(Link)` - margin-top: 15px; - font-family: 'Atlas Grotesk'; - font-weight: bold; - color: ${color.text}; - text-decoration: none; - font-size: 16px; -`; - -const MenuLink = styled(Link)` - color: ${color.text}; -`; - const Content = styled(Flex)` overflow: scroll; position: absolute; @@ -274,6 +257,10 @@ const Content = styled(Flex)` transition: left 200ms ease-in-out; `; +const MenuLink = styled(Link)` + color: ${color.text}; +`; + const Sidebar = styled(Flex)` width: ${layout.sidebarWidth}; margin-left: ${props => (props.editMode ? `-${layout.sidebarWidth}` : 0)}; @@ -282,12 +269,6 @@ const Sidebar = styled(Flex)` transition: margin-left 200ms ease-in-out; `; -const Header = styled(Flex)` - flex-shrink: 0; - padding: ${layout.padding}; - padding-bottom: 10px; -`; - const LinkSection = styled(Flex)` flex-direction: column; padding: 10px 0; diff --git a/frontend/components/Layout/components/HeaderBlock.js b/frontend/components/Layout/components/HeaderBlock.js new file mode 100644 index 000000000..87aab5831 --- /dev/null +++ b/frontend/components/Layout/components/HeaderBlock.js @@ -0,0 +1,42 @@ +// @flow +import React from 'react'; +import styled from 'styled-components'; +import { Link } from 'react-router-dom'; +import { color, layout } from 'styles/constants'; +import type { User, Team } from 'types'; +import Flex from 'components/Flex'; + +type Props = { + user: User, + team: Team, + children?: React$Element, +}; + +function HeaderBlock({ user, team, children }: Props) { + return ( +
+ + {team.name} +

{user.username}

+
+ {children} +
+ ); +} + +const LogoLink = styled(Link)` + margin-top: 15px; + font-family: 'Atlas Grotesk'; + font-weight: bold; + color: ${color.text}; + text-decoration: none; + font-size: 16px; +`; + +const Header = styled(Flex)` + flex-shrink: 0; + padding: ${layout.padding}; + padding-bottom: 10px; +`; + +export default HeaderBlock; From c2c7f48d85ad40746ec1bac2a04d9a90bc1933a0 Mon Sep 17 00:00:00 2001 From: Tom Moor Date: Sun, 3 Sep 2017 23:03:49 -0700 Subject: [PATCH 4/6] Neaten --- .../components/DropdownMenu/DropdownMenu.js | 5 +- frontend/components/Layout/Layout.js | 49 ++++++++++--------- .../Layout/components/HeaderBlock.js | 29 +++++++++-- 3 files changed, 52 insertions(+), 31 deletions(-) diff --git a/frontend/components/DropdownMenu/DropdownMenu.js b/frontend/components/DropdownMenu/DropdownMenu.js index 36c560041..69874c0ad 100644 --- a/frontend/components/DropdownMenu/DropdownMenu.js +++ b/frontend/components/DropdownMenu/DropdownMenu.js @@ -22,6 +22,7 @@ const DropdownMenuItem = ({ onClick, children }: MenuItemProps) => { type DropdownMenuProps = { label: React.Element, children?: React.Element, + style?: Object, }; @observer class DropdownMenu extends React.Component { @@ -42,7 +43,7 @@ type DropdownMenuProps = { {this.menuOpen && - + {this.props.children} } @@ -65,9 +66,7 @@ const Label = styled(Flex).attrs({ })` cursor: pointer; z-index: 1000; - min-height: 43px; - margin: 0 5px; `; const MenuContainer = styled.div` diff --git a/frontend/components/Layout/Layout.js b/frontend/components/Layout/Layout.js index 87ff7dd91..a3d2d5093 100644 --- a/frontend/components/Layout/Layout.js +++ b/frontend/components/Layout/Layout.js @@ -131,29 +131,33 @@ type Props = { user && team && - - }> - - Settings - - - Keyboard shortcuts - - - API - - - Logout - - - + + + + } + > + + Settings + + + Keyboard shortcuts + + + API + + + Logout + + + - - Search - Home + Search Starred @@ -225,7 +229,7 @@ type Props = { const CollectionAction = styled.a` position: absolute; - top: 8px; + top: -2px; right: ${layout.hpadding}; svg { @@ -264,14 +268,13 @@ const MenuLink = styled(Link)` const Sidebar = styled(Flex)` width: ${layout.sidebarWidth}; margin-left: ${props => (props.editMode ? `-${layout.sidebarWidth}` : 0)}; - background: rgba(250, 251, 252, 0.71); - border-right: 1px solid #eceff3; + background: ${color.smoke}; transition: margin-left 200ms ease-in-out; `; const LinkSection = styled(Flex)` flex-direction: column; - padding: 10px 0; + margin: 24px 0; position: relative; `; diff --git a/frontend/components/Layout/components/HeaderBlock.js b/frontend/components/Layout/components/HeaderBlock.js index 87aab5831..cacecf10f 100644 --- a/frontend/components/Layout/components/HeaderBlock.js +++ b/frontend/components/Layout/components/HeaderBlock.js @@ -14,18 +14,21 @@ type Props = { function HeaderBlock({ user, team, children }: Props) { return ( -
- +
+ {team.name} -

{user.username}

+ {user.name}
{children}
); } +const Name = styled.div` + font-size: 13px; +`; + const LogoLink = styled(Link)` - margin-top: 15px; font-family: 'Atlas Grotesk'; font-weight: bold; color: ${color.text}; @@ -36,7 +39,23 @@ const LogoLink = styled(Link)` const Header = styled(Flex)` flex-shrink: 0; padding: ${layout.padding}; - padding-bottom: 10px; + position: relative; + cursor: pointer; + width: 100%; + + &:hover { + background: rgba(0,0,0,.05); + } + + &::after { + content: ""; + left: ${layout.hpadding}; + right: ${layout.hpadding}; + background: rgba(0,0,0,.075); + height: 1px; + position: absolute; + bottom: 0; + } `; export default HeaderBlock; From f4735246ade626281a38923c9237819b92b7a491 Mon Sep 17 00:00:00 2001 From: Tom Moor Date: Mon, 4 Sep 2017 08:32:31 -0700 Subject: [PATCH 5/6] Readability --- frontend/components/Editor/Editor.scss | 2 +- frontend/components/Layout/components/HeaderBlock.js | 10 +++++----- .../Layout/components/SidebarLink/SidebarLink.js | 1 + frontend/styles/base.scss | 2 +- 4 files changed, 8 insertions(+), 7 deletions(-) diff --git a/frontend/components/Editor/Editor.scss b/frontend/components/Editor/Editor.scss index a7694603d..ecc91bb28 100644 --- a/frontend/components/Editor/Editor.scss +++ b/frontend/components/Editor/Editor.scss @@ -1,7 +1,7 @@ .editor { font-weight: 400; font-size: 1em; - line-height: 1.5em; + line-height: 1.7em; width: 100%; color: #1b2631; diff --git a/frontend/components/Layout/components/HeaderBlock.js b/frontend/components/Layout/components/HeaderBlock.js index cacecf10f..8bf4fd57d 100644 --- a/frontend/components/Layout/components/HeaderBlock.js +++ b/frontend/components/Layout/components/HeaderBlock.js @@ -1,7 +1,6 @@ // @flow import React from 'react'; import styled from 'styled-components'; -import { Link } from 'react-router-dom'; import { color, layout } from 'styles/constants'; import type { User, Team } from 'types'; import Flex from 'components/Flex'; @@ -16,19 +15,19 @@ function HeaderBlock({ user, team, children }: Props) { return (
- {team.name} - {user.name} + {team.name} + {user.name} {children}
); } -const Name = styled.div` +const UserName = styled.div` font-size: 13px; `; -const LogoLink = styled(Link)` +const TeamName = styled.div` font-family: 'Atlas Grotesk'; font-weight: bold; color: ${color.text}; @@ -43,6 +42,7 @@ const Header = styled(Flex)` cursor: pointer; width: 100%; + &:active, &:hover { background: rgba(0,0,0,.05); } diff --git a/frontend/components/Layout/components/SidebarLink/SidebarLink.js b/frontend/components/Layout/components/SidebarLink/SidebarLink.js index 7df81e86c..d09f85c3f 100644 --- a/frontend/components/Layout/components/SidebarLink/SidebarLink.js +++ b/frontend/components/Layout/components/SidebarLink/SidebarLink.js @@ -17,6 +17,7 @@ const StyledNavLink = styled(NavLink)` display: block; padding: 5px ${layout.hpadding}; color: ${color.slateDark}; + font-size: 15px; &:hover { color: ${darken(0.1, color.slateDark)}; diff --git a/frontend/styles/base.scss b/frontend/styles/base.scss index 3fcc4acd2..66deb1946 100644 --- a/frontend/styles/base.scss +++ b/frontend/styles/base.scss @@ -21,7 +21,7 @@ html, body, .viewport { body { font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Oxygen, Ubuntu, Cantarell, "Open Sans", "Helvetica Neue", sans-serif; - font-size: 15px; + font-size: 16px; line-height: 1.5; margin: 0; color: #617180; From 24686aac44dbd11d9a0bcc0bc87c24855cd4a101 Mon Sep 17 00:00:00 2001 From: Tom Moor Date: Mon, 4 Sep 2017 08:56:07 -0700 Subject: [PATCH 6/6] Fixes: Scroll to top behavior when changing pages Fixes: Different max-width on docs and other content --- .../CenteredContent/CenteredContent.js | 2 +- frontend/components/Editor/Editor.scss | 2 +- frontend/components/Layout/Layout.js | 16 +++++++--------- frontend/styles/base.scss | 5 ----- 4 files changed, 9 insertions(+), 16 deletions(-) diff --git a/frontend/components/CenteredContent/CenteredContent.js b/frontend/components/CenteredContent/CenteredContent.js index cfc4fe08b..b9f15975a 100644 --- a/frontend/components/CenteredContent/CenteredContent.js +++ b/frontend/components/CenteredContent/CenteredContent.js @@ -12,7 +12,7 @@ const Container = styled.div` `; const Content = styled.div` - max-width: 740px; + max-width: 50em; margin: 0 auto; `; diff --git a/frontend/components/Editor/Editor.scss b/frontend/components/Editor/Editor.scss index ecc91bb28..7508c6021 100644 --- a/frontend/components/Editor/Editor.scss +++ b/frontend/components/Editor/Editor.scss @@ -3,7 +3,7 @@ font-size: 1em; line-height: 1.7em; width: 100%; - color: #1b2631; + color: #1b2830; h1, h2, diff --git a/frontend/components/Layout/Layout.js b/frontend/components/Layout/Layout.js index a3d2d5093..c0a6121ee 100644 --- a/frontend/components/Layout/Layout.js +++ b/frontend/components/Layout/Layout.js @@ -252,13 +252,8 @@ const Container = styled(Flex)` `; const Content = styled(Flex)` - overflow: scroll; - position: absolute; - top: 0; - bottom: 0; - right: 0; - left: ${props => (props.editMode ? 0 : layout.sidebarWidth)}; - transition: left 200ms ease-in-out; + margin-left: ${props => (props.editMode ? 0 : layout.sidebarWidth)}; + transition: margin-left 200ms ease-in-out; `; const MenuLink = styled(Link)` @@ -266,10 +261,13 @@ const MenuLink = styled(Link)` `; const Sidebar = styled(Flex)` + position: fixed; + top: 0; + bottom: 0; + left: ${props => (props.editMode ? `-${layout.sidebarWidth}` : 0)}; width: ${layout.sidebarWidth}; - margin-left: ${props => (props.editMode ? `-${layout.sidebarWidth}` : 0)}; background: ${color.smoke}; - transition: margin-left 200ms ease-in-out; + transition: left 200ms ease-in-out; `; const LinkSection = styled(Flex)` diff --git a/frontend/styles/base.scss b/frontend/styles/base.scss index 66deb1946..cd822c1dc 100644 --- a/frontend/styles/base.scss +++ b/frontend/styles/base.scss @@ -27,11 +27,6 @@ body { color: #617180; background-color: #fff; display: flex; - position: absolute; - top: 0; - right: 0; - bottom: 0; - left: 0; -moz-osx-font-smoothing: grayscale; -webkit-font-smoothing: antialiased;