From 1bab8457faea0784249b038866a2568b4d0e5c43 Mon Sep 17 00:00:00 2001 From: Andrei Shelenhouski Date: Thu, 4 Feb 2021 15:04:41 +0300 Subject: [PATCH 1/2] feat(team): implement createTeam and updateTeam mutations --- src/schema.gql | 15 ++++++++++++ src/teams/models/team.input-type.ts | 21 +++++++++++++++++ src/teams/models/team.interface.ts | 4 ++++ src/teams/resolvers/teams.resolver.ts | 18 ++++++++++++++- src/teams/services/teams.service.ts | 23 ++++++++++++++++++- src/teams/utils/get-next-team-number.util.ts | 24 ++++++++++++++++++++ 6 files changed, 103 insertions(+), 2 deletions(-) create mode 100644 src/teams/models/team.input-type.ts create mode 100644 src/teams/utils/get-next-team-number.util.ts diff --git a/src/schema.gql b/src/schema.gql index 454ff74..534b5a9 100644 --- a/src/schema.gql +++ b/src/schema.gql @@ -46,3 +46,18 @@ type Query { course(id: String!): Course teams: [Team!] } + +type Mutation { + createTeam(team: CreateTeamInput!): Team! + updateTeam(team: UpdateTeamInput!): Team! +} + +input CreateTeamInput { + tgLink: String! + courseId: String! +} + +input UpdateTeamInput { + id: String! + tgLink: String! +} diff --git a/src/teams/models/team.input-type.ts b/src/teams/models/team.input-type.ts new file mode 100644 index 0000000..a403dc4 --- /dev/null +++ b/src/teams/models/team.input-type.ts @@ -0,0 +1,21 @@ +import { Field, InputType } from '@nestjs/graphql'; + +import { ICreateTeam, IUpdateTeam } from './team.interface'; + +@InputType() +export class CreateTeamInput implements ICreateTeam { + @Field() + public tgLink: string; + + @Field() + public courseId: string; +} + +@InputType() +export class UpdateTeamInput implements IUpdateTeam { + @Field() + public id: string; + + @Field() + public tgLink: string; +} diff --git a/src/teams/models/team.interface.ts b/src/teams/models/team.interface.ts index 18a153b..c68fb07 100644 --- a/src/teams/models/team.interface.ts +++ b/src/teams/models/team.interface.ts @@ -6,3 +6,7 @@ export interface ITeam { tgLink: string; memberIds: string[]; } + +export type ICreateTeam = Pick; + +export type IUpdateTeam = Pick; diff --git a/src/teams/resolvers/teams.resolver.ts b/src/teams/resolvers/teams.resolver.ts index 944abeb..3c53017 100644 --- a/src/teams/resolvers/teams.resolver.ts +++ b/src/teams/resolvers/teams.resolver.ts @@ -3,8 +3,10 @@ import { CoursesService } from 'src/courses/services/courses.service'; import { User } from 'src/users/models/user.object-type'; import { UsersService } from 'src/users/services/users.service'; -import { Parent, Query, ResolveField, Resolver } from '@nestjs/graphql'; +import { Args, Mutation, Parent, Query, ResolveField, Resolver } from '@nestjs/graphql'; +import { CreateTeamInput, UpdateTeamInput } from '../models/team.input-type'; +import { ICreateTeam, IUpdateTeam } from '../models/team.interface'; import { Team } from '../models/team.object-type'; import { TeamsService } from '../services/teams.service'; @@ -34,4 +36,18 @@ export class TeamsResolver { return this.usersService.findByIds(memberIds); } + + @Mutation(() => Team, { name: 'createTeam' }) + public async createTeam( + @Args({ name: 'team', type: () => CreateTeamInput }) team: ICreateTeam, + ): Promise { + return this.teamsService.createTeam(team); + } + + @Mutation(() => Team, { name: 'updateTeam' }) + public async updateTeam( + @Args({ name: 'team', type: () => UpdateTeamInput }) team: IUpdateTeam, + ): Promise { + return this.teamsService.updateTeam(team); + } } diff --git a/src/teams/services/teams.service.ts b/src/teams/services/teams.service.ts index da1068e..29f0eab 100644 --- a/src/teams/services/teams.service.ts +++ b/src/teams/services/teams.service.ts @@ -4,6 +4,8 @@ import { Injectable } from '@nestjs/common'; import { InjectRepository } from '@nestjs/typeorm'; import { TeamEntity } from '../models/team.entity'; +import { ICreateTeam, IUpdateTeam } from '../models/team.interface'; +import { getNextTeamNumber } from '../utils/get-next-team-number.util'; @Injectable() export class TeamsService { @@ -19,6 +21,25 @@ export class TeamsService { } public findByIds(ids: string[]): Promise { - return this.teamsRepository.findByIds(ids, { loadRelationIds: true }); + return this.teamsRepository.findByIds(ids, { loadRelationIds: true, order: { number: 'ASC' } }); + } + + public async createTeam(props: ICreateTeam): Promise { + const teams: TeamEntity[] = await this.teamsRepository.find({ courseId: props.courseId }); + const nextNumber: number = getNextTeamNumber(teams); + + const team: TeamEntity = this.teamsRepository.create({ + ...props, + password: Math.random().toString(36).substr(2, 8), + number: nextNumber, + }); + + return this.teamsRepository.save(team); + } + + public async updateTeam(props: IUpdateTeam): Promise { + await this.teamsRepository.update(props.id, { tgLink: props.tgLink }); + + return this.teamsRepository.findOne(props.id); } } diff --git a/src/teams/utils/get-next-team-number.util.ts b/src/teams/utils/get-next-team-number.util.ts new file mode 100644 index 0000000..80ba033 --- /dev/null +++ b/src/teams/utils/get-next-team-number.util.ts @@ -0,0 +1,24 @@ +import { ITeam } from '../models/team.interface'; + +export const getNextTeamNumber: (arr: ITeam[]) => number = (arr: ITeam[]): number => { + let missedNumber: number; + let lastNumber: number; + + const positiveNumbers: number[] = arr.map(item => item.number).sort(); + + if (!positiveNumbers.length) { + return 1; + } + + positiveNumbers.some((element, index) => { + if (element !== index + 1) { + missedNumber = index + 1; + } + + lastNumber = index + 1; + + return missedNumber; + }); + + return missedNumber ?? lastNumber + 1; +}; From e64f8019ac00ea688c6ba5d24808b7f1e49de89b Mon Sep 17 00:00:00 2001 From: Andrei Shelenhouski Date: Thu, 4 Feb 2021 15:07:10 +0300 Subject: [PATCH 2/2] refactor: update create team method --- src/teams/services/teams.service.ts | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/teams/services/teams.service.ts b/src/teams/services/teams.service.ts index 29f0eab..d8fa53f 100644 --- a/src/teams/services/teams.service.ts +++ b/src/teams/services/teams.service.ts @@ -27,10 +27,11 @@ export class TeamsService { public async createTeam(props: ICreateTeam): Promise { const teams: TeamEntity[] = await this.teamsRepository.find({ courseId: props.courseId }); const nextNumber: number = getNextTeamNumber(teams); + const password: string = Math.random().toString(36).substr(2, 8); const team: TeamEntity = this.teamsRepository.create({ ...props, - password: Math.random().toString(36).substr(2, 8), + password, number: nextNumber, });