Skip to content

Commit

Permalink
Merge pull request #177 from Giveth/feature/allow_admin_canceled_proj…
Browse files Browse the repository at this point in the history
…ects

Feature: Add admin canceled project status
  • Loading branch information
mohammadranjbarz authored Oct 25, 2021
2 parents 664700d + f31b139 commit f9f4917
Show file tree
Hide file tree
Showing 5 changed files with 124 additions and 44 deletions.
26 changes: 25 additions & 1 deletion entities/project.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,8 @@ import {
JoinTable,
BaseEntity,
OneToMany,
Index
Index,
AfterUpdate
} from 'typeorm'

import { Organisation } from './organisation'
Expand All @@ -18,6 +19,17 @@ import { Reaction } from './reaction'
import { Category } from './category'
import { User } from './user'
import { ProjectStatus } from './projectStatus'
import ProjectTracker from '../services/segment/projectTracker'

export enum ProjStatus {
rjt = 1,
pen = 2,
clr = 3,
ver = 4,
active = 5,
deactive = 6,
cancel = 7
}

@Entity()
@ObjectType()
Expand Down Expand Up @@ -149,12 +161,19 @@ class Project extends BaseEntity {
@Column({ default: true, nullable: false })
listed: boolean = true

static notifySegment(project: any, eventName: string) {
new ProjectTracker(project, eventName).track()
}

@Field(type => Float, { nullable: true })
reactionsCount () {
return this.reactions ? this.reactions.length : 0
}

// Status 7 is deleted status
mayUpdateStatus (user: User) {
if (this.statusId === ProjStatus.cancel) return false

if (this.users.filter(o => o.id === user.id).length > 0) {
return true
} else {
Expand All @@ -177,6 +196,11 @@ class Project extends BaseEntity {
owner () {
return this.users[0]
}

@AfterUpdate()
notifyProjectEdited() {
Project.notifySegment(this, 'Project edited')
}
}

@Entity()
Expand Down
4 changes: 3 additions & 1 deletion entities/projectStatus.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,8 @@ import {
Column,
Entity,
BaseEntity,
OneToMany
OneToMany,
Index
} from 'typeorm'
import { Project } from './project'

Expand All @@ -19,6 +20,7 @@ export class ProjectStatus extends BaseEntity{
@Column('text', { unique: true })
symbol: string

@Index()
@Field()
@Column({ nullable: true })
name: string
Expand Down
39 changes: 5 additions & 34 deletions resolvers/projectResolver.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import NotificationPayload from '../entities/notificationPayload'
import { Reaction, REACTION_TYPE } from '../entities/reaction'
import { Project, ProjectUpdate } from '../entities/project'
import { Project, ProjectUpdate, ProjStatus } from '../entities/project'
import { InjectRepository } from 'typeorm-typedi-extensions'
import { ProjectStatus } from '../entities/projectStatus'
import { ProjectInput, ImageUpload } from './types/project-input'
Expand Down Expand Up @@ -43,15 +43,6 @@ import {

const analytics = getAnalytics()

enum ProjStatus {
rjt = 1,
pen = 2,
clr = 3,
ver = 4,
act = 5,
can = 6,
del = 7
}
import { inspect } from 'util'
import { errorMessages } from '../utils/errorMessages';
import {
Expand Down Expand Up @@ -238,7 +229,7 @@ export class ProjectResolver {
relations: ['reactions'],
where: {
status: {
id: ProjStatus.act
id: ProjStatus.active
}
}
})
Expand Down Expand Up @@ -380,26 +371,6 @@ export class ProjectResolver {
project.qualityScore = qualityScore
await project.save()

const segmentProject = {
email: user.email,
title: project.title,
lastName: user.lastName,
firstName: user.firstName,
OwnerId: user.id,
slug: project.slug,
walletAddress: project.walletAddress
}

analytics.track(
'Project edited',
`givethId-${user.userId}`,
segmentProject,
null
)

if (config.get('TRIGGER_BUILD_ON_NEW_PROJECT') === 'true')
triggerBuild(projectId)

return project
}

Expand Down Expand Up @@ -541,7 +512,7 @@ export class ProjectResolver {
const slugBase = slugify(projectInput.title)
const slug = await this.getAppropriateSlug(slugBase)
const status = await this.projectStatusRepository.findOne({
id: 5
id: ProjStatus.active
})

const project = this.projectRepository.create({
Expand Down Expand Up @@ -964,7 +935,7 @@ export class ProjectResolver {
): Promise<Boolean> {
try {
const user = await getLoggedInUser(ctx)
const didDeactivate = await this.updateProjectStatus(projectId, ProjStatus.can, user)
const didDeactivate = await this.updateProjectStatus(projectId, ProjStatus.deactive, user)
if (didDeactivate)
{
const project = await Project.findOne({ id: projectId })
Expand Down Expand Up @@ -1002,7 +973,7 @@ export class ProjectResolver {
): Promise<Boolean> {
try {
const user = await getLoggedInUser(ctx)
return await this.updateProjectStatus(projectId, ProjStatus.act, user)
return await this.updateProjectStatus(projectId, ProjStatus.active, user)
} catch (error) {
Logger.captureException(error)
throw error
Expand Down
53 changes: 45 additions & 8 deletions server/bootstrap.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ import { graphqlUploadExpress } from 'graphql-upload'
import { Database, Resource } from '@admin-bro/typeorm';
import { validate } from 'class-validator'

import { Project } from '../entities/project'
import { Project, ProjStatus } from '../entities/project'
import { ProjectStatus } from '../entities/projectStatus';
import { User } from '../entities/user';

Expand All @@ -28,7 +28,12 @@ const AdminBroExpress = require('@admin-bro/express')
const express = require('express')
const bodyParser = require('body-parser')
const cors = require('cors')
const bcrypt = require('bcrypt');
const bcrypt = require('bcrypt')
const segmentProjectStatusEvents = {
'act': 'activated',
'can': 'deactivated',
'del': 'cancelled'
}

// register 3rd party IOC container

Expand Down Expand Up @@ -175,8 +180,16 @@ export async function bootstrap () {
.update<Project>(Project, {listed: list})
.where('project.id IN (:...ids)')
.setParameter('ids', request.query.recordIds.split(','))
.returning('*')
.updateEntity(true)
.execute()

projects.raw.forEach(project => {
Project.notifySegment(
project,
`Project ${list ? 'listed' : 'unlisted'}`
)
})
} catch (error) {
throw error
}
Expand All @@ -186,7 +199,7 @@ export async function bootstrap () {
record.toJSON(context.currentAdmin)
}),
notice: {
message: `Project(s) successfully ${list ? 'listed' : 'delisted'}`,
message: `Project(s) successfully ${list ? 'listed' : 'unlisted'}`,
type: 'success',
}
}
Expand All @@ -199,8 +212,15 @@ export async function bootstrap () {
.update<Project>(Project, {verified: verified})
.where('project.id IN (:...ids)')
.setParameter('ids', request.query.recordIds.split(','))
.returning('*')
.updateEntity(true)
.execute()

projects.raw.forEach(project => {
Project.notifySegment(
project,
`Project ${verified? 'verified' : 'unverified'}`)
})
} catch (error) {
throw error
}
Expand All @@ -225,13 +245,22 @@ export async function bootstrap () {
.update<Project>(Project, {status: projectStatus})
.where('project.id IN (:...ids)')
.setParameter('ids', request.query.recordIds.split(','))
.returning('*')
.updateEntity(true)
.execute()

projects.raw.forEach(project => {
Project.notifySegment(
project,
`Project ${segmentProjectStatusEvents[projectStatus.symbol]}`
)
})
}

} catch (error) {
throw error
}

return {
redirectUrl: 'Project',
records: records.map(record => {
Expand Down Expand Up @@ -340,20 +369,28 @@ export async function bootstrap () {
actionType: 'bulk',
isVisible: true,
handler: async (request, response, context) => {
return updateStatuslProjects(context, request, 5)
return updateStatuslProjects(context, request, ProjStatus.active)
},
component: false,
},
cancelProject: {
deactivateProject: {
actionType: 'bulk',
isVisible: true,
handler: async (request, response, context) => {
return updateStatuslProjects(context, request, 6)
return updateStatuslProjects(context, request, ProjStatus.deactive)
},
component: false,
},
cancelProject: {
actionType: 'bulk',
isVisible: true,
handler: async (request, response, context) => {
return updateStatuslProjects(context, request, ProjStatus.cancel)
},
component: false,
}
}
}
}
},
{ resource: ProjectStatus, options: {
actions: {
Expand Down
46 changes: 46 additions & 0 deletions services/segment/projectTracker.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
import { User } from '../../entities/user';
import { Project } from '../../entities/project';
import { getAnalytics } from '../../analytics';

const analytics = getAnalytics()

/**
* Notifies Segment any event concerning the project
*/
class ProjectTracker {
project: Project
eventName: string
projectOwner?: User

constructor(projectToUpdate: Project, eventTitle: string) {
this.project = projectToUpdate
this.eventName = eventTitle
}

async track() {
this.projectOwner = await User.findOne({ id: Number(this.project.admin) })

if(this.projectOwner) {
analytics.track(
this.eventName,
this.projectOwner.segmentUserId(),
this.segmentProjectAttributes(),
null
)
}
}

private segmentProjectAttributes() {
return {
email: this.projectOwner?.email,
title: this.project.title,
lastName: this.projectOwner?.lastName,
firstName: this.projectOwner?.firstName,
OwnerId: this.projectOwner?.id,
slug: this.project.slug,
walletAddress: this.project.walletAddress
}
}
}

export default ProjectTracker;

0 comments on commit f9f4917

Please sign in to comment.