diff --git a/.flowconfig b/.flowconfig index 1eb0d77d..ba796d40 100644 --- a/.flowconfig +++ b/.flowconfig @@ -24,12 +24,10 @@ emoji=true module.system.node.resolve_dirname=node_modules module.system.node.resolve_dirname=app -module.name_mapper='^\(.*\)\.s?css$' -> 'empty/object' module.name_mapper='^\(.*\)\.md$' -> 'empty/object' module.name_mapper='^shared\/\(.*\)$' -> '/shared/\1' module.file_ext=.js -module.file_ext=.scss module.file_ext=.md module.file_ext=.json diff --git a/__mocks__/styleMock.js b/__mocks__/styleMock.js deleted file mode 100644 index 9775450f..00000000 --- a/__mocks__/styleMock.js +++ /dev/null @@ -1,2 +0,0 @@ -import idObj from 'identity-obj-proxy'; -export default idObj; diff --git a/app/components/Editor/Editor.js b/app/components/Editor/Editor.js index 12ac5024..69168d85 100644 --- a/app/components/Editor/Editor.js +++ b/app/components/Editor/Editor.js @@ -4,7 +4,7 @@ import { Redirect } from 'react-router-dom'; import { observable } from 'mobx'; import { observer } from 'mobx-react'; import { lighten } from 'polished'; -import styled, { withTheme } from 'styled-components'; +import styled, { withTheme, createGlobalStyle } from 'styled-components'; import RichMarkdownEditor from 'rich-markdown-editor'; import Placeholder from 'rich-markdown-editor/lib/components/Placeholder'; import { uploadFile } from 'utils/uploadFile'; @@ -81,15 +81,18 @@ class Editor extends React.Component { if (this.redirectTo) return ; return ( - + + + + ); } } @@ -126,7 +129,151 @@ const StyledEditor = styled(RichMarkdownEditor)` } `; -const EditorTooltip = props => ; +/* +Based on Prism template by Bram de Haan (http://atelierbram.github.io/syntax-highlighting/prism/) +Original Base16 color scheme by Chris Kempson (https://github.com/chriskempson/base16) +*/ +const PrismStyles = createGlobalStyle` + code[class*="language-"], + pre[class*="language-"] { + -webkit-font-smoothing: initial; + font-family: "SFMono-Regular", Consolas, "Liberation Mono", Menlo, Courier, monospace; + font-size: 13px; + line-height: 1.375; + direction: ltr; + text-align: left; + white-space: pre; + word-spacing: normal; + word-break: normal; + -moz-tab-size: 4; + -o-tab-size: 4; + tab-size: 4; + -webkit-hyphens: none; + -moz-hyphens: none; + -ms-hyphens: none; + hyphens: none; + color: #24292e; + } + + /* Code blocks */ + pre[class*="language-"] { + padding: 1em; + margin: .5em 0; + overflow: auto; + } + + /* Inline code */ + :not(pre) > code[class*="language-"] { + padding: .1em; + border-radius: .3em; + } + + .token.comment, + .token.prolog, + .token.doctype, + .token.cdata { + color: #6a737d; + } + + .token.punctuation { + color: #5e6687; + } + + .token.namespace { + opacity: .7; + } + + .token.operator, + .token.boolean, + .token.number { + color: #d73a49; + } + + .token.property { + color: #c08b30; + } + + .token.tag { + color: #3d8fd1; + } + + .token.string { + color: #032f62; + } + + .token.selector { + color: #6679cc; + } + + .token.attr-name { + color: #c76b29; + } + + .token.entity, + .token.url, + .language-css .token.string, + .style .token.string { + color: #22a2c9; + } + + .token.attr-value, + .token.keyword, + .token.control, + .token.directive, + .token.unit { + color: #d73a49; + } + + .token.function { + color: #6f42c1; + } + + .token.statement, + .token.regex, + .token.atrule { + color: #22a2c9; + } + + .token.placeholder, + .token.variable { + color: #3d8fd1; + } + + .token.deleted { + text-decoration: line-through; + } + + .token.inserted { + border-bottom: 1px dotted #202746; + text-decoration: none; + } + + .token.italic { + font-style: italic; + } + + .token.important, + .token.bold { + font-weight: bold; + } + + .token.important { + color: #c94922; + } + + .token.entity { + cursor: help; + } + + pre > code.highlight { + outline: 0.4em solid #c94922; + outline-offset: .4em; + } +`; + +const EditorTooltip = props => ( + +); export default withTheme( // $FlowIssue - https://github.com/facebook/flow/issues/6103 diff --git a/app/components/Tooltip.js b/app/components/Tooltip.js index c8592ddd..d5c12d0c 100644 --- a/app/components/Tooltip.js +++ b/app/components/Tooltip.js @@ -1,204 +1,13 @@ // @flow import * as React from 'react'; -import { TooltipTrigger } from 'pui-react-tooltip'; -import { createGlobalStyle } from 'styled-components'; - -const GlobalStyles = createGlobalStyle` - .tooltip:hover .tooltip-container:not(.tooltip-container-hidden){ - visibility:visible; - opacity:1 - } - .tooltip-container{ - visibility:hidden; - -webkit-transition:opacity ease-out 0.2s; - transition:opacity ease-out 0.2s; - z-index:10; - position:absolute; - bottom:100%; - left:50%; - -webkit-transform:translateX(-50%); - transform:translateX(-50%); - margin:0 0 ${props => props.offset + 8}px 0; - text-align:left - } - .tooltip-container.tooltip-container-visible{ - visibility:visible - } - .tooltip-container.tooltip-hoverable:after{ - content:""; - position:absolute; - width:calc(100% + 16px); - height:calc(100% + 16px); - top:50%; - left:50%; - -webkit-transform:translateX(-50%) translateY(-50%); - transform:translateX(-50%) translateY(-50%) - } - .tooltip-container .tooltip-content{ - white-space:nowrap; - padding:4px 8px; - font-size:12px; - line-height:16px; - font-weight:400; - letter-spacing:0; - text-transform:none; - background-color:${props => props.theme.tooltipBackground}; - color: ${props => props.theme.tooltipText}; - border-radius:2px; - border:1px solid ${props => props.theme.tooltipBackground}; - box-shadow:0px 2px 2px 0px rgba(36, 54, 65, .1),0px 0px 2px 0px rgba(36, 54, 65, .1) - } - .tooltip-container .tooltip-content:before{ - content:""; - z-index:1; - position:absolute; - bottom:-4px; - left:50%; - -webkit-transform:translateX(-50%) rotateZ(45deg); - transform:translateX(-50%) rotateZ(45deg); - background-color:${props => props.theme.tooltipBackground}; - border-bottom:1px solid ${props => props.theme.tooltipBackground}; - border-right:1px solid ${props => props.theme.tooltipBackground}; - width:8px; - height:8px - } - .tooltip-container .tooltip-content:after{ - content:""; - box-sizing:content-box; - z-index:-1; - position:absolute; - bottom: -4px; - left:50%; - -webkit-transform:translateX(-50%) rotateZ(45deg); - transform:translateX(-50%) rotateZ(45deg); - background-color:${props => props.theme.tooltipBackground}; - box-shadow:0px 2px 2px 0px rgba(36, 54, 65, .1),0px 0px 2px 0px rgba(36, 54, 65, .1); - width:8px; - height:8px - } - .tooltip{ - position:relative; - display:inline-block - } - .tooltip.tooltip-bottom .tooltip-container{ - top:100%; - bottom:auto; - left:50%; - -webkit-transform:translateX(-50%); - transform:translateX(-50%); - margin:8px 0 0 0 - } - .tooltip.tooltip-bottom .tooltip-container .tooltip-content:before{ - bottom:auto; - top: -4px; - border-top:1px solid ${props => props.theme.tooltipBackground}; - border-right:none; - border-bottom:none; - border-left:1px solid ${props => props.theme.tooltipBackground} - } - .tooltip.tooltip-bottom .tooltip-container .tooltip-content:after{ - bottom:auto; - top: -4px; - } - .tooltip.tooltip-right .tooltip-container{ - top:50%; - bottom:auto; - left:100%; - -webkit-transform:translatey(-50%); - transform:translatey(-50%); - margin:0 0 0 8px - } - .tooltip.tooltip-right .tooltip-container .tooltip-content:before{ - bottom:auto; - left: -4px; - top:50%; - -webkit-transform:translatey(-50%) rotateZ(45deg); - transform:translatey(-50%) rotateZ(45deg); - border-top:none; - border-right:none; - border-bottom:1px solid ${props => props.theme.tooltipBackground}; - border-left:1px solid ${props => props.theme.tooltipBackground} - } - .tooltip.tooltip-right .tooltip-container .tooltip-content:after{ - bottom:auto; - left: -4px; - top:50%; - -webkit-transform:translatey(-50%) rotateZ(45deg); - transform:translatey(-50%) rotateZ(45deg) - } - .tooltip.tooltip-left .tooltip-container{ - top:50%; - bottom:auto; - right:100%; - left:auto; - -webkit-transform:translatey(-50%); - transform:translatey(-50%); - margin:0 8px 0 0 - } - .tooltip.tooltip-left .tooltip-container .tooltip-content:before{ - bottom:auto; - right: -4px; - left:auto; - top:50%; - -webkit-transform:translatey(-50%) rotateZ(45deg); - transform:translatey(-50%) rotateZ(45deg); - border-top:1px solid ${props => props.theme.tooltipBackground}; - border-right:1px solid ${props => props.theme.tooltipBackground}; - border-bottom:none; - border-left:none - } - .tooltip.tooltip-left .tooltip-container .tooltip-content:after{ - bottom:auto; - right:-4px; - left:auto; - top:50%; - -webkit-transform:translatey(-50%) rotateZ(45deg); - transform:translatey(-50%) rotateZ(45deg) - } - .tooltip-sm.tooltip-container{ - width:120px - } - .tooltip-sm.tooltip-container .tooltip-content{ - white-space:normal - } - .tooltip-md.tooltip-container{ - width:240px - } - .tooltip-md.tooltip-container .tooltip-content{ - white-space:normal - } - .tooltip-lg.tooltip-container{ - width:360px - } - .tooltip-lg.tooltip-container .tooltip-content{ - white-space:normal - } - .tether-element{ - z-index:99 - } - .overlay-trigger{ - color:#1B78B3; - -webkit-transition:all 300ms ease-out; - transition:all 300ms ease-out; - -webkit-transition-property:background-color, color, opacity; - transition-property:background-color, color, opacity - } - .overlay-trigger:hover,.overlay-trigger:focus{ - color:#1f8ace; - cursor:pointer; - outline:none; - text-decoration:none - } - .overlay-trigger:active,.overlay-trigger.active{ - color:#176698 - } -`; +import styled from 'styled-components'; +import Tippy from '@tippy.js/react'; type Props = { tooltip: React.Node, placement?: 'top' | 'bottom' | 'left' | 'right', children: React.Node, - offset?: number, + delay?: number, }; class Tooltip extends React.Component { @@ -207,15 +16,33 @@ class Tooltip extends React.Component { } render() { - const { offset = 0, ...rest } = this.props; + const { tooltip, delay = 50, children, ...rest } = this.props; return ( - - - - + + {children} + ); } } +const StyledTippy = styled(Tippy)` + font-size: 13px; + background-color: ${props => props.theme.tooltipBackground}; + color: ${props => props.theme.tooltipText}; + + svg { + fill: ${props => props.theme.tooltipBackground}; + } +`; + export default Tooltip; diff --git a/app/index.js b/app/index.js index 78919791..57bf7e97 100644 --- a/app/index.js +++ b/app/index.js @@ -4,7 +4,6 @@ import { render } from 'react-dom'; import { Provider } from 'mobx-react'; import { BrowserRouter as Router } from 'react-router-dom'; import stores from 'stores'; -import 'shared/styles/prism.css'; import ErrorBoundary from 'components/ErrorBoundary'; import ScrollToTop from 'components/ScrollToTop'; diff --git a/app/scenes/Settings/People.js b/app/scenes/Settings/People.js index 27614cad..9249a8b6 100644 --- a/app/scenes/Settings/People.js +++ b/app/scenes/Settings/People.js @@ -6,6 +6,8 @@ import { observer, inject } from 'mobx-react'; import AuthStore from 'stores/AuthStore'; import UsersStore from 'stores/UsersStore'; +import Empty from 'components/Empty'; +import { ListPlaceholder } from 'components/LoadingPlaceholder'; import Modal from 'components/Modal'; import Button from 'components/Button'; import Invite from 'scenes/Invite'; @@ -50,8 +52,13 @@ class People extends React.Component { users = this.props.users.orderedData; } else if (filter === 'admins') { users = this.props.users.admins; + } else if (filter === 'suspended') { + users = this.props.users.suspended; } + const showLoading = this.props.users.isFetching && !users.length; + const showEmpty = this.props.users.isLoaded && !users.length; + return ( @@ -79,6 +86,11 @@ class People extends React.Component { Admins + {currentUser.isAdmin && ( + + Suspended + + )} Everyone @@ -92,6 +104,9 @@ class People extends React.Component { /> ))} + {showEmpty && No people to see here.} + {showLoading && } + { return filter(this.orderedData, user => !user.isSuspended); } + @computed + get suspended(): User[] { + return filter(this.orderedData, user => user.isSuspended); + } + @computed get admins(): User[] { return filter(this.orderedData, user => user.isAdmin); diff --git a/flow-typed/npm/css-loader_vx.x.x.js b/flow-typed/npm/css-loader_vx.x.x.js deleted file mode 100644 index 4f234162..00000000 --- a/flow-typed/npm/css-loader_vx.x.x.js +++ /dev/null @@ -1,94 +0,0 @@ -// flow-typed signature: a2009a68b1b7bd5dceaf1f252af90495 -// flow-typed version: <>/css-loader_v^0.28.7/flow_v0.86.0 - -/** - * This is an autogenerated libdef stub for: - * - * 'css-loader' - * - * Fill this stub out by replacing all the `any` types. - * - * Once filled out, we encourage you to share your work with the - * community by sending a pull request to: - * https://github.com/flowtype/flow-typed - */ - -declare module 'css-loader' { - declare module.exports: any; -} - -/** - * We include stubs for each file inside this npm package in case you need to - * require those files directly. Feel free to delete any files that aren't - * needed. - */ -declare module 'css-loader/lib/compile-exports' { - declare module.exports: any; -} - -declare module 'css-loader/lib/createResolver' { - declare module.exports: any; -} - -declare module 'css-loader/lib/css-base' { - declare module.exports: any; -} - -declare module 'css-loader/lib/getImportPrefix' { - declare module.exports: any; -} - -declare module 'css-loader/lib/getLocalIdent' { - declare module.exports: any; -} - -declare module 'css-loader/lib/loader' { - declare module.exports: any; -} - -declare module 'css-loader/lib/localsLoader' { - declare module.exports: any; -} - -declare module 'css-loader/lib/processCss' { - declare module.exports: any; -} - -declare module 'css-loader/locals' { - declare module.exports: any; -} - -// Filename aliases -declare module 'css-loader/index' { - declare module.exports: $Exports<'css-loader'>; -} -declare module 'css-loader/index.js' { - declare module.exports: $Exports<'css-loader'>; -} -declare module 'css-loader/lib/compile-exports.js' { - declare module.exports: $Exports<'css-loader/lib/compile-exports'>; -} -declare module 'css-loader/lib/createResolver.js' { - declare module.exports: $Exports<'css-loader/lib/createResolver'>; -} -declare module 'css-loader/lib/css-base.js' { - declare module.exports: $Exports<'css-loader/lib/css-base'>; -} -declare module 'css-loader/lib/getImportPrefix.js' { - declare module.exports: $Exports<'css-loader/lib/getImportPrefix'>; -} -declare module 'css-loader/lib/getLocalIdent.js' { - declare module.exports: $Exports<'css-loader/lib/getLocalIdent'>; -} -declare module 'css-loader/lib/loader.js' { - declare module.exports: $Exports<'css-loader/lib/loader'>; -} -declare module 'css-loader/lib/localsLoader.js' { - declare module.exports: $Exports<'css-loader/lib/localsLoader'>; -} -declare module 'css-loader/lib/processCss.js' { - declare module.exports: $Exports<'css-loader/lib/processCss'>; -} -declare module 'css-loader/locals.js' { - declare module.exports: $Exports<'css-loader/locals'>; -} diff --git a/flow-typed/npm/extract-text-webpack-plugin_vx.x.x.js b/flow-typed/npm/extract-text-webpack-plugin_vx.x.x.js deleted file mode 100644 index a2e5bf41..00000000 --- a/flow-typed/npm/extract-text-webpack-plugin_vx.x.x.js +++ /dev/null @@ -1,74 +0,0 @@ -// flow-typed signature: f0eb83cfad1c4097bee63b0b5c61a251 -// flow-typed version: <>/extract-text-webpack-plugin_v^3.0.2/flow_v0.86.0 - -/** - * This is an autogenerated libdef stub for: - * - * 'extract-text-webpack-plugin' - * - * Fill this stub out by replacing all the `any` types. - * - * Once filled out, we encourage you to share your work with the - * community by sending a pull request to: - * https://github.com/flowtype/flow-typed - */ - -declare module 'extract-text-webpack-plugin' { - declare module.exports: any; -} - -/** - * We include stubs for each file inside this npm package in case you need to - * require those files directly. Feel free to delete any files that aren't - * needed. - */ -declare module 'extract-text-webpack-plugin/dist/cjs' { - declare module.exports: any; -} - -declare module 'extract-text-webpack-plugin/dist/index' { - declare module.exports: any; -} - -declare module 'extract-text-webpack-plugin/dist/lib/ExtractedModule' { - declare module.exports: any; -} - -declare module 'extract-text-webpack-plugin/dist/lib/ExtractTextPluginCompilation' { - declare module.exports: any; -} - -declare module 'extract-text-webpack-plugin/dist/lib/helpers' { - declare module.exports: any; -} - -declare module 'extract-text-webpack-plugin/dist/lib/OrderUndefinedError' { - declare module.exports: any; -} - -declare module 'extract-text-webpack-plugin/dist/loader' { - declare module.exports: any; -} - -// Filename aliases -declare module 'extract-text-webpack-plugin/dist/cjs.js' { - declare module.exports: $Exports<'extract-text-webpack-plugin/dist/cjs'>; -} -declare module 'extract-text-webpack-plugin/dist/index.js' { - declare module.exports: $Exports<'extract-text-webpack-plugin/dist/index'>; -} -declare module 'extract-text-webpack-plugin/dist/lib/ExtractedModule.js' { - declare module.exports: $Exports<'extract-text-webpack-plugin/dist/lib/ExtractedModule'>; -} -declare module 'extract-text-webpack-plugin/dist/lib/ExtractTextPluginCompilation.js' { - declare module.exports: $Exports<'extract-text-webpack-plugin/dist/lib/ExtractTextPluginCompilation'>; -} -declare module 'extract-text-webpack-plugin/dist/lib/helpers.js' { - declare module.exports: $Exports<'extract-text-webpack-plugin/dist/lib/helpers'>; -} -declare module 'extract-text-webpack-plugin/dist/lib/OrderUndefinedError.js' { - declare module.exports: $Exports<'extract-text-webpack-plugin/dist/lib/OrderUndefinedError'>; -} -declare module 'extract-text-webpack-plugin/dist/loader.js' { - declare module.exports: $Exports<'extract-text-webpack-plugin/dist/loader'>; -} diff --git a/flow-typed/npm/normalize.css_v7.x.x.js b/flow-typed/npm/normalize.css_v7.x.x.js deleted file mode 100644 index a17c0d86..00000000 --- a/flow-typed/npm/normalize.css_v7.x.x.js +++ /dev/null @@ -1,9 +0,0 @@ -// flow-typed signature: b0a8c8851219a1c2a933509d842e0bc8 -// flow-typed version: 4a2d036a51/normalize.css_v7.x.x/flow_>=v0.34.x - -// normalize.css may be imported for side-effects, -// e.g. to force webpack to bundle it alongside CSS modules - -declare module "normalize.css" { - declare export default empty -} diff --git a/flow-typed/npm/style-loader_vx.x.x.js b/flow-typed/npm/style-loader_vx.x.x.js deleted file mode 100644 index eddd543b..00000000 --- a/flow-typed/npm/style-loader_vx.x.x.js +++ /dev/null @@ -1,66 +0,0 @@ -// flow-typed signature: 04c6b5a073e3f6e139d773f3fa779b3f -// flow-typed version: <>/style-loader_v^0.18.2/flow_v0.86.0 - -/** - * This is an autogenerated libdef stub for: - * - * 'style-loader' - * - * Fill this stub out by replacing all the `any` types. - * - * Once filled out, we encourage you to share your work with the - * community by sending a pull request to: - * https://github.com/flowtype/flow-typed - */ - -declare module 'style-loader' { - declare module.exports: any; -} - -/** - * We include stubs for each file inside this npm package in case you need to - * require those files directly. Feel free to delete any files that aren't - * needed. - */ -declare module 'style-loader/lib/addStyles' { - declare module.exports: any; -} - -declare module 'style-loader/lib/addStyleUrl' { - declare module.exports: any; -} - -declare module 'style-loader/lib/urls' { - declare module.exports: any; -} - -declare module 'style-loader/url' { - declare module.exports: any; -} - -declare module 'style-loader/useable' { - declare module.exports: any; -} - -// Filename aliases -declare module 'style-loader/index' { - declare module.exports: $Exports<'style-loader'>; -} -declare module 'style-loader/index.js' { - declare module.exports: $Exports<'style-loader'>; -} -declare module 'style-loader/lib/addStyles.js' { - declare module.exports: $Exports<'style-loader/lib/addStyles'>; -} -declare module 'style-loader/lib/addStyleUrl.js' { - declare module.exports: $Exports<'style-loader/lib/addStyleUrl'>; -} -declare module 'style-loader/lib/urls.js' { - declare module.exports: $Exports<'style-loader/lib/urls'>; -} -declare module 'style-loader/url.js' { - declare module.exports: $Exports<'style-loader/url'>; -} -declare module 'style-loader/useable.js' { - declare module.exports: $Exports<'style-loader/useable'>; -} diff --git a/package.json b/package.json index 6bd9eb6d..ab20d03c 100644 --- a/package.json +++ b/package.json @@ -29,7 +29,6 @@ ], "moduleNameMapper": { "^shared/(.*)$": "/shared/$1", - "^.*[.](s?css|css)$": "/__mocks__/styleMock.js", "^.*[.](gif|ttf|eot|svg)$": "/__test__/fileMock.js" }, "moduleFileExtensions": [ @@ -56,6 +55,7 @@ "url": "git+ssh://git@github.com/outline/outline.git" }, "dependencies": { + "@tippy.js/react": "^2.2.2", "@tommoor/remove-markdown": "0.3.1", "autotrack": "^2.4.1", "aws-sdk": "^2.135.0", @@ -81,13 +81,11 @@ "bull": "^3.5.2", "cancan": "3.1.0", "copy-to-clipboard": "^3.0.6", - "css-loader": "^0.28.7", "date-fns": "1.29.0", "debug": "^4.1.1", "dotenv": "^4.0.0", "emoji-regex": "^6.5.1", "exports-loader": "^0.6.4", - "extract-text-webpack-plugin": "^3.0.2", "file-loader": "^1.1.6", "flow-typed": "^2.4.0", "fs-extra": "^4.0.2", @@ -125,7 +123,6 @@ "pg": "^6.1.5", "pg-hstore": "2.3.2", "polished": "1.2.1", - "pui-react-tooltip": "^8.3.3", "query-string": "^4.3.4", "randomstring": "1.1.5", "raw-loader": "^0.5.1", @@ -141,7 +138,7 @@ "react-router-dom": "^4.3.1", "react-waypoint": "^7.3.1", "redis": "^2.6.2", - "rich-markdown-editor": "^9.8.1", + "rich-markdown-editor": "^9.8.2", "safestart": "1.1.0", "sequelize": "^5.8.12", "sequelize-cli": "^5.5.0", @@ -151,8 +148,7 @@ "socket.io-redis": "^5.2.0", "socketio-auth": "^0.1.1", "string-replace-to-array": "^1.0.3", - "style-loader": "^0.18.2", - "styled-components": "^4.2.0", + "styled-components": "^4.3.2", "styled-components-breakpoint": "^2.1.1", "styled-components-grid": "^2.2.1", "styled-normalize": "^8.0.4", diff --git a/server/static/dev.html b/server/static/dev.html index 28e6b2c8..c403c9d9 100644 --- a/server/static/dev.html +++ b/server/static/dev.html @@ -2,7 +2,6 @@ Outline -