diff --git a/api/server/api/team-member.ts b/api/server/api/team-member.ts index 629bee79..feeaa38f 100644 --- a/api/server/api/team-member.ts +++ b/api/server/api/team-member.ts @@ -105,13 +105,14 @@ router.get('/teams', async (req, res, next) => { router.post('/discussions/add', async (req, res, next) => { try { - const { name, teamId, memberIds = [] } = req.body; + const { name, teamId, memberIds = [], notificationType } = req.body; const discussion = await Discussion.add({ userId: req.user.id, name, teamId, memberIds, + notificationType, }); res.json({ discussion }); @@ -122,13 +123,14 @@ router.post('/discussions/add', async (req, res, next) => { router.post('/discussions/edit', async (req, res, next) => { try { - const { name, id, memberIds = [] } = req.body; + const { name, id, memberIds = [], notificationType } = req.body; await Discussion.edit({ userId: req.user.id, name, id, memberIds, + notificationType, }); res.json({ done: 1 }); diff --git a/api/server/models/Discussion.ts b/api/server/models/Discussion.ts index ed08a597..c575616c 100644 --- a/api/server/models/Discussion.ts +++ b/api/server/models/Discussion.ts @@ -30,6 +30,12 @@ const mongoSchema = new mongoose.Schema({ required: true, default: Date.now, }, + notificationType: { + type: String, + enum: ['default', 'email'], + required: true, + default: 'default', + }, }); interface IDiscussionDocument extends mongoose.Document { @@ -55,11 +61,13 @@ interface IDiscussionModel extends mongoose.Model { userId, teamId, memberIds, + notificationType, }: { name: string; userId: string; teamId: string; memberIds: string[]; + notificationType: string; }): Promise; edit({ @@ -67,11 +75,13 @@ interface IDiscussionModel extends mongoose.Model { id, name, memberIds, + notificationType, }: { userId: string; id: string; name: string; memberIds: string[]; + notificationType: string; }): Promise<{ teamId: string }>; delete({ userId, id }: { userId: string; id: string }): Promise<{ teamId: string }>; @@ -111,7 +121,7 @@ class DiscussionClass extends mongoose.Model { return { discussions }; } - public static async add({ name, userId, teamId, memberIds = [] }) { + public static async add({ name, userId, teamId, memberIds = [], notificationType }) { if (!name) { throw new Error('Bad data'); } @@ -127,10 +137,11 @@ class DiscussionClass extends mongoose.Model { slug, memberIds: uniq([userId, ...memberIds]), createdAt: new Date(), + notificationType, }); } - public static async edit({ userId, id, name, memberIds = [] }) { + public static async edit({ userId, id, name, memberIds = [], notificationType }) { if (!id) { throw new Error('Bad data'); } @@ -146,7 +157,7 @@ class DiscussionClass extends mongoose.Model { }); if (discussion.createdUserId !== userId && team.teamLeaderId !== userId) { - throw new Error('Permission denied. Only create user or team leader can update.'); + throw new Error('Permission denied. Only author or team leader can edit Discussion.'); } await this.updateOne( @@ -154,6 +165,7 @@ class DiscussionClass extends mongoose.Model { { name, memberIds: uniq([userId, ...memberIds]), + notificationType, }, ); diff --git a/app/components/discussions/CreateDiscussionForm.tsx b/app/components/discussions/CreateDiscussionForm.tsx index a57016d6..78e9ac8c 100644 --- a/app/components/discussions/CreateDiscussionForm.tsx +++ b/app/components/discussions/CreateDiscussionForm.tsx @@ -1,5 +1,10 @@ import Button from '@material-ui/core/Button'; import Drawer from '@material-ui/core/Drawer'; +import FormControl from '@material-ui/core/FormControl'; +import FormHelperText from '@material-ui/core/FormHelperText'; +import InputLabel from '@material-ui/core/InputLabel'; +import MenuItem from '@material-ui/core/MenuItem'; +import Select from '@material-ui/core/Select'; import { withStyles } from '@material-ui/core/styles'; import TextField from '@material-ui/core/TextField'; import { inject } from 'mobx-react'; @@ -33,6 +38,7 @@ type State = { memberIds: string[]; disabled: boolean; content: string; + notificationType: string; }; class CreateDiscussionForm extends React.Component { @@ -41,6 +47,7 @@ class CreateDiscussionForm extends React.Component { content: '', memberIds: [], disabled: false, + notificationType: 'default', }; public handleClose = () => { @@ -73,26 +80,6 @@ class CreateDiscussionForm extends React.Component {

Create new Discussion

-

-

- {' '} -

- - {isMobile ?

: null} -


{ />

{this.renderMemberChooser()} +

+
+ + + Notification type + + + Choose how to notify members about new Posts inside Discussion. + + +


this.setState({ content })} members={Array.from(store.currentTeam.members.values())} /> +


+

+ {' '} +

+ + {isMobile ?

: null} +

@@ -134,7 +163,8 @@ class CreateDiscussionForm extends React.Component { return; } - const { name, memberIds, content } = this.state; + const { name, memberIds, content, notificationType } = this.state; + if (!name) { notify('Name is required'); return; @@ -145,6 +175,16 @@ class CreateDiscussionForm extends React.Component { return; } + if (!notificationType) { + notify('Please select notification type.'); + return; + } + + if (!memberIds || memberIds.length < 1) { + notify('Please assign at least one person to this Discussion.'); + return; + } + NProgress.start(); try { this.setState({ disabled: true }); @@ -152,6 +192,7 @@ class CreateDiscussionForm extends React.Component { const discussion = await currentTeam.addDiscussion({ name, memberIds, + notificationType, }); await discussion.addPost(content); diff --git a/app/components/discussions/EditDiscussionForm.tsx b/app/components/discussions/EditDiscussionForm.tsx index 20bf650d..b87afea1 100644 --- a/app/components/discussions/EditDiscussionForm.tsx +++ b/app/components/discussions/EditDiscussionForm.tsx @@ -4,6 +4,11 @@ import DialogActions from '@material-ui/core/DialogActions'; import DialogContent from '@material-ui/core/DialogContent'; import DialogContentText from '@material-ui/core/DialogContentText'; import DialogTitle from '@material-ui/core/DialogTitle'; +import FormControl from '@material-ui/core/FormControl'; +import FormHelperText from '@material-ui/core/FormHelperText'; +import InputLabel from '@material-ui/core/InputLabel'; +import MenuItem from '@material-ui/core/MenuItem'; +import Select from '@material-ui/core/Select'; import TextField from '@material-ui/core/TextField'; import { inject } from 'mobx-react'; import NProgress from 'nprogress'; @@ -26,6 +31,7 @@ type State = { memberIds: string[]; disabled: boolean; discussionId: string; + notificationType: string; }; class EditDiscussionForm extends React.Component { @@ -40,6 +46,7 @@ class EditDiscussionForm extends React.Component { name: (discussion && discussion.name) || '', memberIds: (discussion && discussion.memberIds) || [], discussionId: discussion._id, + notificationType: discussion.notificationType || 'default', }; } @@ -48,6 +55,7 @@ class EditDiscussionForm extends React.Component { memberIds: [], disabled: false, discussionId: '', + notificationType: 'default', }; public render() { @@ -71,7 +79,29 @@ class EditDiscussionForm extends React.Component {

{this.renderMemberChooser()} +

+
+ + Notification type + + + Choose how to notify members about new Posts inside Discussion. + + +


+