From d5192acabf601fd418fdaf5465e0247ef43e1426 Mon Sep 17 00:00:00 2001 From: Tom Moor Date: Mon, 24 Jun 2019 22:14:59 -0700 Subject: [PATCH] feat: invites (#967) * stub invite endpoint * feat: First pass invite UI * feat: allow removing invite rows * First pass: sending logic * fix: label accessibility * fix: add button submits incorrect permissions middleware flow error * :green_heart: * Error handling, email filtering, tests * Flow * Add Invite to people page Remove old Tip * Add copy link to subdomain --- app/components/Button.js | 2 +- app/components/Input.js | 26 ++++- app/components/Sidebar/Main.js | 28 +++++ app/components/TipInvite.js | 61 ---------- app/components/VisuallyHidden.js | 13 +++ app/index.js | 3 + app/scenes/Dashboard.js | 5 - app/scenes/Invite.js | 165 +++++++++++++++++++++++++++ app/scenes/Settings/People.js | 31 +++++ app/stores/UsersStore.js | 7 ++ server/api/middlewares/pagination.js | 6 +- server/api/users.js | 26 +++-- server/commands/userInviter.js | 57 +++++++++ server/commands/userInviter.test.js | 56 +++++++++ server/emails/InviteEmail.js | 59 ++++++++++ server/events.js | 31 +++-- server/mailer.js | 18 +++ server/models/Collection.js | 2 - server/policies/user.js | 4 + server/services/notifications.js | 6 +- server/services/slack.js | 6 +- 21 files changed, 509 insertions(+), 103 deletions(-) delete mode 100644 app/components/TipInvite.js create mode 100644 app/components/VisuallyHidden.js create mode 100644 app/scenes/Invite.js create mode 100644 server/commands/userInviter.js create mode 100644 server/commands/userInviter.test.js create mode 100644 server/emails/InviteEmail.js diff --git a/app/components/Button.js b/app/components/Button.js index 5e3818075..aef597472 100644 --- a/app/components/Button.js +++ b/app/components/Button.js @@ -114,7 +114,7 @@ export default function Button({ const hasIcon = icon !== undefined; return ( - + {hasIcon && icon} {hasText && } diff --git a/app/components/Input.js b/app/components/Input.js index c092ad0df..7b5fe266f 100644 --- a/app/components/Input.js +++ b/app/components/Input.js @@ -3,6 +3,7 @@ import * as React from 'react'; import { observer } from 'mobx-react'; import { observable } from 'mobx'; import styled from 'styled-components'; +import VisuallyHidden from 'components/VisuallyHidden'; import Flex from 'shared/components/Flex'; const RealTextarea = styled.textarea` @@ -38,9 +39,10 @@ const RealInput = styled.input` `; const Wrapper = styled.div` + flex: ${props => (props.flex ? '1' : '0')}; max-width: ${props => (props.short ? '350px' : '100%')}; min-height: ${({ minHeight }) => (minHeight ? `${minHeight}px` : '0')}; - max-height: ${({ maxHeight }) => (maxHeight ? `${maxHeight}px` : 'auto')}; + max-height: ${({ maxHeight }) => (maxHeight ? `${maxHeight}px` : 'initial')}; `; export const Outline = styled(Flex)` @@ -70,6 +72,8 @@ export type Props = { value?: string, label?: string, className?: string, + labelHidden?: boolean, + flex?: boolean, short?: boolean, }; @@ -86,14 +90,28 @@ class Input extends React.Component { }; render() { - const { type = 'text', label, className, short, ...rest } = this.props; + const { + type = 'text', + label, + className, + short, + flex, + labelHidden, + ...rest + } = this.props; const InputComponent = type === 'textarea' ? RealTextarea : RealInput; + const wrappedLabel = {label}; return ( - +