diff --git a/app/components/Button.js b/app/components/Button.js index a37921bf..c6eafb4c 100644 --- a/app/components/Button.js +++ b/app/components/Button.js @@ -1,60 +1,53 @@ // @flow import * as React from 'react'; import styled from 'styled-components'; -import { darken } from 'polished'; +import { darken, lighten } from 'polished'; const RealButton = styled.button` display: inline-block; margin: 0; padding: 0; border: 0; - background: ${props => props.theme.primary}; + background: ${props => props.theme.blackLight}; color: ${props => props.theme.white}; + box-shadow: rgba(0, 0, 0, 0.2) 0px 1px 2px; border-radius: 4px; - font-size: 15px; + font-size: 12px; + font-weight: 500; height: 36px; text-decoration: none; + text-transform: uppercase; flex-shrink: 0; outline: none; cursor: pointer; + user-select: none; &::-moz-focus-inner { padding: 0; border: 0; } - &:hover { - background: ${props => darken(0.05, props.theme.primary)}; - } - svg { - position: relative; - top: 0.05em; + &:hover { + background: ${props => darken(0.05, props.theme.blackLight)}; } &:disabled { - opacity: 0.6; cursor: default; + pointer-events: none; + color: ${props => lighten(0.2, props.theme.blackLight)}; } ${props => - props.light && + props.neutral && ` - color: ${props.theme.slate}; - background: transparent; - border: 1px solid ${props.theme.slate}; + background: ${props.theme.white}; + color: ${props.theme.text}; + box-shadow: rgba(0, 0, 0, 0.07) 0px 1px 2px; + border: 1px solid ${props.theme.slateLight}; &:hover { - background: transparent; - color: ${props.theme.slateDark}; - border: 1px solid ${props.theme.slateDark}; - } - `} ${props => - props.neutral && - ` - background: ${props.theme.slate}; - - &:hover { - background: ${darken(0.05, props.theme.slate)}; + background: ${darken(0.05, props.theme.white)}; + border: 1px solid ${darken(0.05, props.theme.slateLight)}; } `} ${props => props.danger && @@ -72,7 +65,7 @@ const Label = styled.span` white-space: nowrap; text-overflow: ellipsis; - ${props => props.hasIcon && 'padding-left: 2px;'}; + ${props => props.hasIcon && 'padding-left: 4px;'}; `; const Inner = styled.span` @@ -84,7 +77,7 @@ const Inner = styled.span` ${props => props.hasIcon && - (props.small ? 'padding-left: 6px;' : 'padding-left: 10px;')}; + (props.small ? 'padding-left: 6px;' : 'padding-left: 8px;')}; `; export type Props = { diff --git a/app/components/Sidebar/components/Collections.js b/app/components/Sidebar/components/Collections.js index ffc04331..9e7c2076 100644 --- a/app/components/Sidebar/components/Collections.js +++ b/app/components/Sidebar/components/Collections.js @@ -25,38 +25,40 @@ type Props = { @observer class Collections extends React.Component { + isPreloaded: boolean = !!this.props.collections.orderedData.length; + componentDidMount() { this.props.collections.fetchPage({ limit: 100 }); } render() { const { history, location, collections, ui, documents } = this.props; + const content = ( + +
Collections
+ {collections.orderedData.map(collection => ( + + ))} + } + > + New collection… + +
+ ); return ( - collections.isLoaded && ( - - -
Collections
- {collections.orderedData.map(collection => ( - - ))} - } - > - New collection… - -
-
- ) + collections.isLoaded && + (this.isPreloaded ? content : {content}) ); } } diff --git a/app/components/Tip.js b/app/components/Tip.js index 8836f801..0301accf 100644 --- a/app/components/Tip.js +++ b/app/components/Tip.js @@ -1,5 +1,7 @@ // @flow import * as React from 'react'; +import { observable } from 'mobx'; +import { observer } from 'mobx-react'; import styled from 'styled-components'; import { CloseIcon } from 'outline-icons'; import Button from './Button'; @@ -12,14 +14,10 @@ type Props = { disabled?: boolean, }; -type State = { - isHidden: boolean, -}; - -class Tip extends React.Component { - state = { - isHidden: window.localStorage.getItem(this.storageId) === 'hidden', - }; +@observer +class Tip extends React.Component { + @observable + isHidden: boolean = window.localStorage.getItem(this.storageId) === 'hidden'; get storageId() { return `tip-${this.props.id}`; @@ -27,28 +25,29 @@ class Tip extends React.Component { hide = () => { window.localStorage.setItem(this.storageId, 'hidden'); - this.setState({ isHidden: true }); + this.isHidden = true; }; render() { const { children } = this.props; - if (this.props.disabled || this.state.isHidden) return null; + if (this.props.disabled || this.isHidden) return null; return ( - + {children} - +    {collection.private && ( diff --git a/app/scenes/CollectionPermissions/CollectionPermissions.js b/app/scenes/CollectionPermissions/CollectionPermissions.js index 29eec2cc..205c69d6 100644 --- a/app/scenes/CollectionPermissions/CollectionPermissions.js +++ b/app/scenes/CollectionPermissions/CollectionPermissions.js @@ -27,7 +27,8 @@ type Props = { @observer class CollectionPermissions extends React.Component { - @observable isSaving: boolean; + @observable isEdited: boolean = false; + @observable isSaving: boolean = false; @observable filter: string; componentDidMount() { @@ -35,10 +36,17 @@ class CollectionPermissions extends React.Component { this.props.collection.fetchUsers(); } + componentWillUnmount() { + if (this.isEdited) { + this.props.ui.showToast('Permissions updated'); + } + } + handlePrivateChange = async (ev: SyntheticInputEvent<*>) => { const { collection } = this.props; try { + this.isEdited = true; collection.private = ev.target.checked; await collection.save(); @@ -53,6 +61,7 @@ class CollectionPermissions extends React.Component { handleAddUser = user => { try { + this.isEdited = true; this.props.collection.addUser(user); } catch (err) { this.props.ui.showToast('Could not add user'); @@ -61,6 +70,7 @@ class CollectionPermissions extends React.Component { handleRemoveUser = user => { try { + this.isEdited = true; this.props.collection.removeUser(user); } catch (err) { this.props.ui.showToast('Could not remove user'); diff --git a/app/scenes/CollectionPermissions/components/UserListItem.js b/app/scenes/CollectionPermissions/components/UserListItem.js index 3c74209a..51e54a78 100644 --- a/app/scenes/CollectionPermissions/components/UserListItem.js +++ b/app/scenes/CollectionPermissions/components/UserListItem.js @@ -18,7 +18,7 @@ const UserListItem = ({ user, onAdd, showAdd }: Props) => { image={} actions={ showAdd ? ( - ) : ( diff --git a/app/scenes/DocumentDelete.js b/app/scenes/DocumentDelete.js index e69be468..359d5119 100644 --- a/app/scenes/DocumentDelete.js +++ b/app/scenes/DocumentDelete.js @@ -45,11 +45,12 @@ class DocumentDelete extends React.Component {
- Are you sure? Deleting the {document.title}{' '} - document is permanent and will also delete all of its history. + Are you sure about that? Deleting the{' '} + {document.title} document is permanent, will delete + all of its history, and any child documents.
diff --git a/app/scenes/Settings/components/SlackButton.js b/app/scenes/Settings/components/SlackButton.js index 259aa5d7..13f72dcc 100644 --- a/app/scenes/Settings/components/SlackButton.js +++ b/app/scenes/Settings/components/SlackButton.js @@ -17,7 +17,11 @@ function SlackButton({ state, scopes, redirectUri, label }: Props) { (window.location.href = slackAuth(state, scopes, redirectUri)); return ( -