Skip to content
This repository has been archived by the owner on Nov 21, 2020. It is now read-only.

Commit

Permalink
feat(deal/ticket/task): Add watch option for deal, ticket, task and p…
Browse files Browse the repository at this point in the history
…ipeline

Closes erxes/erxes#1013
  • Loading branch information
munkhjin0223 committed Jul 8, 2019
1 parent 5bf17bc commit d6dcabc
Show file tree
Hide file tree
Showing 28 changed files with 453 additions and 246 deletions.
29 changes: 29 additions & 0 deletions src/__tests__/boardMutations.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -206,6 +206,35 @@ describe('Test boards mutations', () => {
expect(updatedPipelineToOrder.order).toBe(9);
});

test('Watch pipeline', async () => {
const mutation = `
mutation pipelinesWatch($_id: String!, $isAdd: Boolean, $type: String!) {
pipelinesWatch(_id: $_id, isAdd: $isAdd, type: $type) {
_id
isWatched
}
}
`;

const watchAddPipeline = await graphqlRequest(
mutation,
'pipelinesWatch',
{ _id: pipeline._id, isAdd: true, type: 'deal' },
context,
);

expect(watchAddPipeline.isWatched).toBe(true);

const watchRemovePipeline = await graphqlRequest(
mutation,
'pipelinesWatch',
{ _id: pipeline._id, isAdd: false, type: 'deal' },
context,
);

expect(watchRemovePipeline.isWatched).toBe(false);
});

test('Remove pipeline', async () => {
// disconnect stages connected to pipeline
await Stages.updateMany({}, { $set: { pipelineId: 'fakePipelineId' } });
Expand Down
19 changes: 19 additions & 0 deletions src/__tests__/dealMutations.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -142,4 +142,23 @@ describe('Test deals mutations', () => {

expect(await Deals.findOne({ _id: deal._id })).toBe(null);
});

test('Watch deal', async () => {
const mutation = `
mutation dealsWatch($_id: String!, $isAdd: Boolean!) {
dealsWatch(_id: $_id, isAdd: $isAdd) {
_id
isWatched
}
}
`;

const watchAddDeal = await graphqlRequest(mutation, 'dealsWatch', { _id: deal._id, isAdd: true }, context);

expect(watchAddDeal.isWatched).toBe(true);

const watchRemoveDeal = await graphqlRequest(mutation, 'dealsWatch', { _id: deal._id, isAdd: false }, context);

expect(watchRemoveDeal.isWatched).toBe(false);
});
});
19 changes: 19 additions & 0 deletions src/__tests__/taskMutations.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -142,4 +142,23 @@ describe('Test tasks mutations', () => {

expect(await Tasks.findOne({ _id: task._id })).toBe(null);
});

test('Watch task', async () => {
const mutation = `
mutation tasksWatch($_id: String!, $isAdd: Boolean!) {
tasksWatch(_id: $_id, isAdd: $isAdd) {
_id
isWatched
}
}
`;

const watchAddTask = await graphqlRequest(mutation, 'tasksWatch', { _id: task._id, isAdd: true }, context);

expect(watchAddTask.isWatched).toBe(true);

const watchRemoveTask = await graphqlRequest(mutation, 'tasksWatch', { _id: task._id, isAdd: false }, context);

expect(watchRemoveTask.isWatched).toBe(false);
});
});
24 changes: 24 additions & 0 deletions src/__tests__/ticketMutations.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -142,4 +142,28 @@ describe('Test tickets mutations', () => {

expect(await Tickets.findOne({ _id: ticket._id })).toBe(null);
});

test('Watch ticket', async () => {
const mutation = `
mutation ticketsWatch($_id: String!, $isAdd: Boolean!) {
ticketsWatch(_id: $_id, isAdd: $isAdd) {
_id
isWatched
}
}
`;

const watchAddTicket = await graphqlRequest(mutation, 'ticketsWatch', { _id: ticket._id, isAdd: true }, context);

expect(watchAddTicket.isWatched).toBe(true);

const watchRemoveTicket = await graphqlRequest(
mutation,
'ticketsWatch',
{ _id: ticket._id, isAdd: false },
context,
);

expect(watchRemoveTicket.isWatched).toBe(false);
});
});
30 changes: 30 additions & 0 deletions src/data/permissions/actions/permission.ts
Original file line number Diff line number Diff line change
Expand Up @@ -151,6 +151,7 @@ export const moduleObjects = {
'dealPipelinesAdd',
'dealPipelinesEdit',
'dealPipelinesUpdateOrder',
'dealPipelinesWatch',
'dealPipelinesRemove',
'dealStagesAdd',
'dealStagesEdit',
Expand All @@ -160,6 +161,7 @@ export const moduleObjects = {
'dealsEdit',
'dealsRemove',
'dealsUpdateOrder',
'dealsWatch',
],
},
{
Expand Down Expand Up @@ -190,6 +192,10 @@ export const moduleObjects = {
name: 'dealPipelinesUpdateOrder',
description: 'Update pipeline order',
},
{
name: 'dealPipelinesWatch',
description: 'Deal pipeline watch',
},
{
name: 'dealStagesAdd',
description: 'Add deal stage',
Expand Down Expand Up @@ -222,6 +228,10 @@ export const moduleObjects = {
name: 'dealsRemove',
description: 'Remove deal',
},
{
name: 'dealsWatch',
description: 'Watch deal',
},
],
},
tickets: {
Expand All @@ -239,6 +249,7 @@ export const moduleObjects = {
'ticketPipelinesAdd',
'ticketPipelinesEdit',
'ticketPipelinesUpdateOrder',
'ticketPipelinesWatch',
'ticketPipelinesRemove',
'ticketStagesAdd',
'ticketStagesEdit',
Expand All @@ -248,6 +259,7 @@ export const moduleObjects = {
'ticketsEdit',
'ticketsRemove',
'ticketsUpdateOrder',
'ticketsWatch',
],
},
{
Expand All @@ -274,6 +286,10 @@ export const moduleObjects = {
name: 'ticketPipelinesRemove',
description: 'Remove ticket pipeline',
},
{
name: 'ticketPipelinesWatch',
description: 'Ticket pipeline watch',
},
{
name: 'ticketPipelinesUpdateOrder',
description: 'Update pipeline order',
Expand Down Expand Up @@ -310,6 +326,10 @@ export const moduleObjects = {
name: 'ticketsRemove',
description: 'Remove ticket',
},
{
name: 'ticketsWatch',
description: 'Watch ticket',
},
],
},
tasks: {
Expand All @@ -327,6 +347,7 @@ export const moduleObjects = {
'taskPipelinesAdd',
'taskPipelinesEdit',
'taskPipelinesUpdateOrder',
'taskPipelinesWatch',
'taskPipelinesRemove',
'taskStagesAdd',
'taskStagesEdit',
Expand All @@ -336,6 +357,7 @@ export const moduleObjects = {
'tasksEdit',
'tasksRemove',
'tasksUpdateOrder',
'tasksWatch',
],
},
{
Expand All @@ -362,6 +384,10 @@ export const moduleObjects = {
name: 'taskPipelinesRemove',
description: 'Remove task pipeline',
},
{
name: 'taskPipelinesWatch',
description: 'Task pipeline watch',
},
{
name: 'taskPipelinesUpdateOrder',
description: 'Update pipeline order',
Expand Down Expand Up @@ -398,6 +424,10 @@ export const moduleObjects = {
name: 'tasksRemove',
description: 'Remove task',
},
{
name: 'tasksWatch',
description: 'Watch task',
},
],
},
engages: {
Expand Down
54 changes: 32 additions & 22 deletions src/data/resolvers/boardUtils.ts
Original file line number Diff line number Diff line change
@@ -1,20 +1,39 @@
import { Boards, Pipelines, Stages } from '../../db/models';
import { NOTIFICATION_TYPES } from '../../db/models/definitions/constants';
import { IDealDocument } from '../../db/models/definitions/deals';
import { ITicketDocument } from '../../db/models/definitions/tickets';
import { IUserDocument } from '../../db/models/definitions/users';
import { can } from '../permissions/utils';
import { checkLogin } from '../permissions/wrappers';
import utils from '../utils';

export const notifiedUserIds = async (item: any) => {
const userIds: string[] = [];

if (item.assignedUserIds) {
userIds.concat(item.assignedUserIds);
}

if (item.watchedUserIds) {
userIds.concat(item.watchedUserIds);
}

const stage = await Stages.getStage(item.stageId || '');
const pipeline = await Pipelines.getPipeline(stage.pipelineId || '');

if (pipeline.watchedUserIds) {
userIds.concat(pipeline.watchedUserIds);
}

return userIds;
};

/**
* Send notification to all members of this content except the sender
*/
export const sendNotifications = async (
stageId: string,
user: IUserDocument,
type: string,
assignedUsers: string[],
userIds: string[],
content: string,
contentType: string,
) => {
Expand All @@ -38,23 +57,19 @@ export const sendNotifications = async (
link: `/${contentType}/board?id=${pipeline.boardId}&pipelineId=${pipeline._id}`,

// exclude current user
receivers: (assignedUsers || []).filter(id => id !== user._id),
receivers: userIds.filter(id => id !== user._id),
});
};

export const manageNotifications = async (
collection: any,
item: IDealDocument | ITicketDocument,
user: IUserDocument,
type: string,
) => {
export const manageNotifications = async (collection: any, item: any, user: IUserDocument, type: string) => {
const { _id } = item;
const oldItem = await collection.findOne({ _id });
const oldAssignedUserIds = oldItem ? oldItem.assignedUserIds || [] : [];
const assignedUserIds = item.assignedUserIds || [];

const oldUserIds = await notifiedUserIds(oldItem);
const userIds = await notifiedUserIds(item);

// new assignee users
const newUserIds = assignedUserIds.filter(userId => oldAssignedUserIds.indexOf(userId) < 0);
const newUserIds = userIds.filter(userId => oldUserIds.indexOf(userId) < 0);

if (newUserIds.length > 0) {
await sendNotifications(
Expand All @@ -68,7 +83,7 @@ export const manageNotifications = async (
}

// remove from assignee users
const removedUserIds = oldAssignedUserIds.filter(userId => assignedUserIds.indexOf(userId) < 0);
const removedUserIds = oldUserIds.filter(userId => userIds.indexOf(userId) < 0);

if (removedUserIds.length > 0) {
await sendNotifications(
Expand All @@ -87,19 +102,14 @@ export const manageNotifications = async (
item.stageId || '',
user,
NOTIFICATION_TYPES[`${type.toUpperCase()}_EDIT`],
assignedUserIds,
userIds,
`'{userName}' edited your ${type} '${item.name}'`,
type,
);
}
};

export const itemsChange = async (
collection: any,
item: IDealDocument | ITicketDocument,
type: string,
destinationStageId: string,
) => {
export const itemsChange = async (collection: any, item: any, type: string, destinationStageId: string) => {
const oldItem = await collection.findOne({ _id: item._id });
const oldStageId = oldItem ? oldItem.stageId || '' : '';

Expand All @@ -118,7 +128,7 @@ export const itemsChange = async (
return content;
};

export const boardId = async (item: IDealDocument | ITicketDocument) => {
export const boardId = async (item: any) => {
const stage = await Stages.findOne({ _id: item.stageId });

if (!stage) {
Expand Down
13 changes: 12 additions & 1 deletion src/data/resolvers/deals.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import { Companies, Customers, Pipelines, Products, Stages, Users } from '../../db/models';
import { IDealDocument } from '../../db/models/definitions/deals';
import { IUserDocument } from '../../db/models/definitions/users';
import { boardId } from './boardUtils';

export default {
Expand Down Expand Up @@ -66,7 +67,17 @@ export default {
return boardId(deal);
},

async stage(deal: IDealDocument) {
stage(deal: IDealDocument) {
return Stages.findOne({ _id: deal.stageId });
},

isWatched(deal: IDealDocument, _args, { user }: { user: IUserDocument }) {
const watchedUserIds = deal.watchedUserIds || [];

if (watchedUserIds.includes(user._id)) {
return true;
}

return false;
},
};
19 changes: 19 additions & 0 deletions src/data/resolvers/mutations/boards.ts
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,25 @@ const boardMutations = {
return Pipelines.updateOrder(orders);
},

/**
* Watch pipeline
*/
async pipelinesWatch(
_root,
{ _id, isAdd, type }: { _id: string; isAdd: boolean; type: string },
{ user }: { user: IUserDocument },
) {
await checkPermission(type, user, 'pipelinesWatch');

const pipeline = await Pipelines.findOne({ _id });

if (!pipeline) {
throw new Error('Pipeline not found');
}

return Pipelines.watchPipeline(_id, isAdd, user._id);
},

/**
* Remove pipeline
*/
Expand Down
Loading

0 comments on commit d6dcabc

Please sign in to comment.