diff --git a/app/components/Sidebar/components/HeaderBlock.js b/app/components/Sidebar/components/HeaderBlock.js index 3b97dc65..1dea87eb 100644 --- a/app/components/Sidebar/components/HeaderBlock.js +++ b/app/components/Sidebar/components/HeaderBlock.js @@ -3,7 +3,7 @@ import * as React from 'react'; import styled, { withTheme } from 'styled-components'; import { ExpandedIcon } from 'outline-icons'; import Flex from 'shared/components/Flex'; -import TeamLogo from './TeamLogo'; +import TeamLogo from 'shared/components/TeamLogo'; type Props = { teamName: string, diff --git a/server/auth/index.js b/server/auth/index.js index 87250372..642877db 100644 --- a/server/auth/index.js +++ b/server/auth/index.js @@ -20,7 +20,7 @@ router.use('/', google.routes()); router.get('/redirect', auth(), async ctx => { const user = ctx.state.user; - // transfer cookie from root to subdomain specific + // transfer access token cookie from root to subdomain ctx.cookies.set('accessToken', undefined, { httpOnly: true, domain: stripSubdomain(ctx.request.hostname), diff --git a/server/middlewares/authentication.js b/server/middlewares/authentication.js index 62f4a88b..a09ed0a2 100644 --- a/server/middlewares/authentication.js +++ b/server/middlewares/authentication.js @@ -118,6 +118,7 @@ export default function auth(options?: { required?: boolean } = {}) { [team.subdomain]: { name: team.name, logo: team.logo, + url: team.url, expires, }, }); diff --git a/server/pages/components/Layout.js b/server/pages/components/Layout.js index addec1d4..42a18567 100644 --- a/server/pages/components/Layout.js +++ b/server/pages/components/Layout.js @@ -15,9 +15,10 @@ export const screenshotUrl = `${process.env.URL}/screenshot.png`; type Props = { children?: React.Node, + sessions?: Object, }; -function Layout({ children }: Props) { +function Layout({ children, sessions }: Props) { return ( @@ -65,7 +66,7 @@ function Layout({ children }: Props) { {'{{CSS}}'} - + {children} diff --git a/server/pages/components/Navigation.js b/server/pages/components/Navigation.js index e64f3bc4..75c01d63 100644 --- a/server/pages/components/Navigation.js +++ b/server/pages/components/Navigation.js @@ -1,8 +1,10 @@ // @flow import * as React from 'react'; +import { sortBy } from 'lodash'; import styled from 'styled-components'; import breakpoint from 'styled-components-breakpoint'; import Centered from './Centered'; +import TeamLogo from '../../../shared/components/TeamLogo'; import { developers, changelog, @@ -13,7 +15,18 @@ import { spectrumUrl, } from '../../../shared/utils/routeHelpers'; -function TopNavigation() { +type Sessions = { + [subdomain: string]: { + name: string, + logo: string, + expires: string, + url: string, + }, +}; + +function TopNavigation({ sessions }: { sessions: ?Sessions }) { + const orderedSessions = sortBy(sessions, 'name'); + return ( ); @@ -74,13 +103,8 @@ const MenuLinkStyle = props => ` } `; -const Menu = styled.ul` - margin: 0; - padding: 0; - list-style: none; -`; - const MenuItem = styled.li` + position: relative; display: inline-block; margin: 0 0 0 40px; @@ -89,6 +113,33 @@ const MenuItem = styled.li` } ${MenuLinkStyle}; + + ${props => + props.highlighted && + ` + position: relative; + border: 2px solid ${props.theme.slate}; + border-radius: 4px; + padding: 6px 8px; + margin-top: -6px; + margin-bottom: -6px; + + &:hover { + border: 2px solid ${props.theme.slateDark}; + + > a { + color: ${props.theme.slateDark}; + } + } + + > a:hover { + text-decoration: none; + } + `}; + + &:hover ol { + display: block; + } `; const MenuItemDesktop = styled(MenuItem)` @@ -99,6 +150,42 @@ const MenuItemDesktop = styled(MenuItem)` `}; `; +const Menu = styled.ul` + margin: 0; + padding: 0; + list-style: none; + + ol { + display: none; + position: absolute; + margin: 0; + padding: 0; + right: 0; + top: 32px; + + background: #fff; + border-radius: 4px; + min-width: 160px; + padding: 0 0.5em; + box-shadow: 0 0 0 1px rgba(0, 0, 0, 0.05), 0 4px 8px rgba(0, 0, 0, 0.08), + 0 2px 4px rgba(0, 0, 0, 0.08); + + ${MenuItem} { + padding: 0.5em 0; + margin: 0; + } + + ${MenuItem} a { + display: flex; + align-items: center; + } + + ${TeamLogo} { + margin-right: 0.5em; + } + } +`; + const Nav = styled(Centered)` display: flex; padding: 20px 0; diff --git a/server/routes.js b/server/routes.js index 725a6f1a..1e073d56 100644 --- a/server/routes.js +++ b/server/routes.js @@ -66,21 +66,12 @@ router.get('/changelog', async ctx => { // home page router.get('/', async ctx => { const lastSignedIn = ctx.cookies.get('lastSignedIn'); - const sessions = JSON.parse(ctx.cookies.get('sessions') || '{}'); const domain = parseDomain(ctx.request.hostname); const subdomain = domain ? domain.subdomain : undefined; - console.log('domain', domain); - console.log('subdomain', subdomain); + const accessToken = ctx.cookies.get('accessToken'); - let accessToken; - if (subdomain) { - accessToken = sessions[subdomain] && sessions[subdomain].accessToken; - } else { - accessToken = sessions.root - ? sessions.root.accessToken - : ctx.cookies.get('accessToken'); - } console.log('accessToken', accessToken); + ctx.set('Cache-Control', 'no-cache'); if (accessToken) { return renderapp(ctx); diff --git a/server/utils/renderpage.js b/server/utils/renderpage.js index ed57c8ac..43fbd3f1 100644 --- a/server/utils/renderpage.js +++ b/server/utils/renderpage.js @@ -13,10 +13,11 @@ import theme from '../../shared/styles/theme'; const sheet = new ServerStyleSheet(); export default function renderpage(ctx: Object, children: React.Node) { + const sessions = JSON.parse(ctx.cookies.get('sessions') || '{}'); const html = ReactDOMServer.renderToString( - {children} + {children} ); diff --git a/app/components/Sidebar/components/TeamLogo.js b/shared/components/TeamLogo.js similarity index 100% rename from app/components/Sidebar/components/TeamLogo.js rename to shared/components/TeamLogo.js