refactor: refactoring Team-Collections with reordering in self-host (HBE-150) (#34)
* chore: removed firebase module as a dependency from team-collection module * chore: modified team-collection resolver file to use input-args types * chore: modified getTeamOfCollection service method and resolver * chore: modified getParentOfCollection service method in team-collection module * chore: modified getChildrenOfCollection service method in team-collection module * chore: added new fields to TeamCollection model in prisma schema file * chore: modified getCollection service method and resolver in team-collection module * chore: modified createCollection service method and resolver in team-collection module * chore: created cast helper function to resolve issue with creation mutation in team-collection * chore: modified teamCollectionRemoved subscription return types * chore: removed return types from subscriptions in team-collection module * chore: removed all instances of getTeamCollections service method in team-collection module * feat: added mutation to handle moving collections and supporting subscriptions * feat: added mutation to re-ordering team-collection order * chore: added teacher comments to both collection modules * test: added test cases for getTeamOfCollection service method * test: added test cases for getParentOfCollection service method * test: added test cases for getChildrenOfCollection service method * test: added test cases for getTeamRootCollections service method * test: added test cases for getCollection service method * test: added test cases for createCollection service method * chore: renamed renameCollection to renameUserCollection in UserCollection module * test: added test cases for renameCollection service method * test: added test cases for deleteCollection service method * test: added test cases for moveCollection service method * test: added test cases for updateCollectionOrder service method * chore: added import and export to JSON mutations to team-collection module * chore: created replaceCollectionsWithJSON mutation in team-collection module * chore: moved the mutation and service method of importCollectionFromFirestore to the end of file * chore: added helper comments to all import,export functions * chore: exportCollectionsToJSON service method orders collections and requests in ascending order * chore: added test cases for importCollectionsFromJSON service method * chore: added ToDo to write test cases for exportCollectionsToJSON * chore: removed prisma migration folder * chore: completed all changes requested in inital PR review * chore: completed all changes requested in second PR review * chore: completed all changes requested in third PR review
This commit is contained in:
@@ -12,6 +12,7 @@ import {
|
||||
TEAM_INVALID_COLL_ID,
|
||||
TEAM_REQ_NOT_MEMBER,
|
||||
} from 'src/errors';
|
||||
import * as E from 'fp-ts/Either';
|
||||
|
||||
@Injectable()
|
||||
export class GqlCollectionTeamMemberGuard implements CanActivate {
|
||||
@@ -29,6 +30,7 @@ export class GqlCollectionTeamMemberGuard implements CanActivate {
|
||||
if (!requireRoles) throw new Error(BUG_TEAM_NO_REQUIRE_TEAM_ROLE);
|
||||
|
||||
const gqlExecCtx = GqlExecutionContext.create(context);
|
||||
|
||||
const { user } = gqlExecCtx.getContext().req;
|
||||
if (user == undefined) throw new Error(BUG_AUTH_NO_USER_CTX);
|
||||
|
||||
@@ -38,10 +40,10 @@ export class GqlCollectionTeamMemberGuard implements CanActivate {
|
||||
const collection = await this.teamCollectionService.getCollection(
|
||||
collectionID,
|
||||
);
|
||||
if (!collection) throw new Error(TEAM_INVALID_COLL_ID);
|
||||
if (E.isLeft(collection)) throw new Error(TEAM_INVALID_COLL_ID);
|
||||
|
||||
const member = await this.teamService.getTeamMember(
|
||||
collection.teamID,
|
||||
collection.right.teamID,
|
||||
user.uid,
|
||||
);
|
||||
if (!member) throw new Error(TEAM_REQ_NOT_MEMBER);
|
||||
|
||||
@@ -0,0 +1,100 @@
|
||||
import { ArgsType, Field, ID } from '@nestjs/graphql';
|
||||
import { PaginationArgs } from 'src/types/input-types.args';
|
||||
|
||||
@ArgsType()
|
||||
export class GetRootTeamCollectionsArgs extends PaginationArgs {
|
||||
@Field(() => ID, { name: 'teamID', description: 'ID of the team' })
|
||||
teamID: string;
|
||||
}
|
||||
|
||||
@ArgsType()
|
||||
export class CreateRootTeamCollectionArgs {
|
||||
@Field(() => ID, { name: 'teamID', description: 'ID of the team' })
|
||||
teamID: string;
|
||||
|
||||
@Field({ name: 'title', description: 'Title of the new collection' })
|
||||
title: string;
|
||||
}
|
||||
|
||||
@ArgsType()
|
||||
export class CreateChildTeamCollectionArgs {
|
||||
@Field(() => ID, {
|
||||
name: 'collectionID',
|
||||
description: 'ID of the parent to the new collection',
|
||||
})
|
||||
collectionID: string;
|
||||
|
||||
@Field({ name: 'childTitle', description: 'Title of the new collection' })
|
||||
childTitle: string;
|
||||
}
|
||||
|
||||
@ArgsType()
|
||||
export class RenameTeamCollectionArgs {
|
||||
@Field(() => ID, {
|
||||
name: 'collectionID',
|
||||
description: 'ID of the collection',
|
||||
})
|
||||
collectionID: string;
|
||||
|
||||
@Field({
|
||||
name: 'newTitle',
|
||||
description: 'The updated title of the collection',
|
||||
})
|
||||
newTitle: string;
|
||||
}
|
||||
|
||||
@ArgsType()
|
||||
export class MoveTeamCollectionArgs {
|
||||
@Field(() => ID, {
|
||||
name: 'parentCollectionID',
|
||||
description: 'ID of the parent to the new collection',
|
||||
nullable: true,
|
||||
})
|
||||
parentCollectionID: string;
|
||||
|
||||
@Field(() => ID, {
|
||||
name: 'collectionID',
|
||||
description: 'ID of the collection',
|
||||
})
|
||||
collectionID: string;
|
||||
}
|
||||
|
||||
@ArgsType()
|
||||
export class UpdateTeamCollectionOrderArgs {
|
||||
@Field(() => ID, {
|
||||
name: 'collectionID',
|
||||
description: 'ID of the collection',
|
||||
})
|
||||
collectionID: string;
|
||||
|
||||
@Field(() => ID, {
|
||||
name: 'destCollID',
|
||||
description:
|
||||
'ID of the collection that comes after the updated collection in its new position',
|
||||
nullable: true,
|
||||
})
|
||||
destCollID: string;
|
||||
}
|
||||
|
||||
@ArgsType()
|
||||
export class ReplaceTeamCollectionArgs {
|
||||
@Field(() => ID, {
|
||||
name: 'teamID',
|
||||
description: 'Id of the team to add to',
|
||||
})
|
||||
teamID: string;
|
||||
|
||||
@Field({
|
||||
name: 'jsonString',
|
||||
description: 'JSON string to replace with',
|
||||
})
|
||||
jsonString: string;
|
||||
|
||||
@Field(() => ID, {
|
||||
name: 'parentCollectionID',
|
||||
description:
|
||||
'ID to the collection to which to import to (null if to import to the root of team)',
|
||||
nullable: true,
|
||||
})
|
||||
parentCollectionID?: string;
|
||||
}
|
||||
@@ -12,6 +12,25 @@ export class TeamCollection {
|
||||
})
|
||||
title: string;
|
||||
|
||||
parentID: string | null;
|
||||
@Field(() => ID, {
|
||||
description: 'ID of the collection',
|
||||
nullable: true,
|
||||
})
|
||||
parentID: string;
|
||||
teamID: string;
|
||||
}
|
||||
|
||||
@ObjectType()
|
||||
export class CollectionReorderData {
|
||||
@Field({
|
||||
description: 'Team Collection being moved',
|
||||
})
|
||||
collection: TeamCollection;
|
||||
|
||||
@Field({
|
||||
description:
|
||||
'Team Collection succeeding the collection being moved in its new position',
|
||||
nullable: true,
|
||||
})
|
||||
nextCollection?: TeamCollection;
|
||||
}
|
||||
|
||||
@@ -5,17 +5,10 @@ import { TeamCollectionResolver } from './team-collection.resolver';
|
||||
import { GqlCollectionTeamMemberGuard } from './guards/gql-collection-team-member.guard';
|
||||
import { TeamModule } from '../team/team.module';
|
||||
import { UserModule } from '../user/user.module';
|
||||
// import { FirebaseModule } from '../firebase/firebase.module';
|
||||
import { PubSubModule } from '../pubsub/pubsub.module';
|
||||
|
||||
@Module({
|
||||
imports: [
|
||||
PrismaModule,
|
||||
// FirebaseModule,
|
||||
TeamModule,
|
||||
UserModule,
|
||||
PubSubModule,
|
||||
],
|
||||
imports: [PrismaModule, TeamModule, UserModule, PubSubModule],
|
||||
providers: [
|
||||
TeamCollectionService,
|
||||
TeamCollectionResolver,
|
||||
|
||||
@@ -8,7 +8,7 @@ import {
|
||||
Subscription,
|
||||
ID,
|
||||
} from '@nestjs/graphql';
|
||||
import { TeamCollection } from './team-collection.model';
|
||||
import { CollectionReorderData, TeamCollection } from './team-collection.model';
|
||||
import { Team, TeamMemberRole } from '../team/team.model';
|
||||
import { TeamCollectionService } from './team-collection.service';
|
||||
import { GqlAuthGuard } from '../guards/gql-auth.guard';
|
||||
@@ -17,6 +17,18 @@ import { UseGuards } from '@nestjs/common';
|
||||
import { RequiresTeamRole } from '../team/decorators/requires-team-role.decorator';
|
||||
import { GqlCollectionTeamMemberGuard } from './guards/gql-collection-team-member.guard';
|
||||
import { PubSubService } from 'src/pubsub/pubsub.service';
|
||||
import { PaginationArgs } from 'src/types/input-types.args';
|
||||
import {
|
||||
CreateChildTeamCollectionArgs,
|
||||
CreateRootTeamCollectionArgs,
|
||||
GetRootTeamCollectionsArgs,
|
||||
MoveTeamCollectionArgs,
|
||||
RenameTeamCollectionArgs,
|
||||
ReplaceTeamCollectionArgs,
|
||||
UpdateTeamCollectionOrderArgs,
|
||||
} from './input-type.args';
|
||||
import * as E from 'fp-ts/Either';
|
||||
import { throwErr } from 'src/utils';
|
||||
|
||||
@Resolver(() => TeamCollection)
|
||||
export class TeamCollectionResolver {
|
||||
@@ -30,58 +42,43 @@ export class TeamCollectionResolver {
|
||||
description: 'Team the collection belongs to',
|
||||
complexity: 5,
|
||||
})
|
||||
team(@Parent() collection: TeamCollection): Promise<Team> {
|
||||
return this.teamCollectionService.getTeamOfCollection(collection.id);
|
||||
async team(@Parent() collection: TeamCollection) {
|
||||
const team = await this.teamCollectionService.getTeamOfCollection(
|
||||
collection.id,
|
||||
);
|
||||
if (E.isLeft(team)) throwErr(team.left);
|
||||
return team.right;
|
||||
}
|
||||
|
||||
@ResolveField(() => TeamCollection, {
|
||||
description:
|
||||
'The collection who is the parent of this collection (null if this is root collection)',
|
||||
description: 'Return the parent Team Collection (null if root )',
|
||||
nullable: true,
|
||||
complexity: 3,
|
||||
})
|
||||
parent(@Parent() collection: TeamCollection): Promise<TeamCollection | null> {
|
||||
async parent(@Parent() collection: TeamCollection) {
|
||||
return this.teamCollectionService.getParentOfCollection(collection.id);
|
||||
}
|
||||
|
||||
@ResolveField(() => [TeamCollection], {
|
||||
description: 'List of children collection',
|
||||
description: 'List of children Team Collections',
|
||||
complexity: 3,
|
||||
})
|
||||
children(
|
||||
async children(
|
||||
@Parent() collection: TeamCollection,
|
||||
@Args({
|
||||
name: 'cursor',
|
||||
nullable: true,
|
||||
description: 'ID of the last returned collection (for pagination)',
|
||||
})
|
||||
cursor?: string,
|
||||
): Promise<TeamCollection[]> {
|
||||
@Args() args: PaginationArgs,
|
||||
) {
|
||||
return this.teamCollectionService.getChildrenOfCollection(
|
||||
collection.id,
|
||||
cursor ?? null,
|
||||
args.cursor,
|
||||
args.take,
|
||||
);
|
||||
}
|
||||
|
||||
// Queries
|
||||
// @Query(() => String, {
|
||||
// description:
|
||||
// 'Returns the JSON string giving the collections and their contents of the team',
|
||||
// })
|
||||
// @UseGuards(GqlAuthGuard, GqlTeamMemberGuard)
|
||||
// @RequiresTeamRole(
|
||||
// TeamMemberRole.VIEWER,
|
||||
// TeamMemberRole.EDITOR,
|
||||
// TeamMemberRole.OWNER,
|
||||
// )
|
||||
// exportCollectionsToJSON(
|
||||
// @Args({ name: 'teamID', description: 'ID of the team', type: () => ID }) teamID: string,
|
||||
// ): Promise<string> {
|
||||
// return this.teamCollectionService.exportCollectionsToJSON(teamID);
|
||||
// }
|
||||
|
||||
@Query(() => [TeamCollection], {
|
||||
description: 'Returns the collections of the team',
|
||||
@Query(() => String, {
|
||||
description:
|
||||
'Returns the JSON string giving the collections and their contents of the team',
|
||||
})
|
||||
@UseGuards(GqlAuthGuard, GqlTeamMemberGuard)
|
||||
@RequiresTeamRole(
|
||||
@@ -89,27 +86,20 @@ export class TeamCollectionResolver {
|
||||
TeamMemberRole.EDITOR,
|
||||
TeamMemberRole.OWNER,
|
||||
)
|
||||
rootCollectionsOfTeam(
|
||||
async exportCollectionsToJSON(
|
||||
@Args({ name: 'teamID', description: 'ID of the team', type: () => ID })
|
||||
teamID: string,
|
||||
@Args({
|
||||
name: 'cursor',
|
||||
nullable: true,
|
||||
type: () => ID,
|
||||
description: 'ID of the last returned collection (for pagination)',
|
||||
})
|
||||
cursor?: string,
|
||||
): Promise<TeamCollection[]> {
|
||||
return this.teamCollectionService.getTeamRootCollections(
|
||||
) {
|
||||
const jsonString = await this.teamCollectionService.exportCollectionsToJSON(
|
||||
teamID,
|
||||
cursor ?? null,
|
||||
);
|
||||
|
||||
if (E.isLeft(jsonString)) throwErr(jsonString.left as string);
|
||||
return jsonString.right;
|
||||
}
|
||||
|
||||
@Query(() => [TeamCollection], {
|
||||
description: 'Returns the collections of the team',
|
||||
deprecationReason:
|
||||
'Deprecated because of no practical use. Use `rootCollectionsOfTeam` instead.',
|
||||
description: 'Returns the collections of a team',
|
||||
})
|
||||
@UseGuards(GqlAuthGuard, GqlTeamMemberGuard)
|
||||
@RequiresTeamRole(
|
||||
@@ -117,25 +107,16 @@ export class TeamCollectionResolver {
|
||||
TeamMemberRole.EDITOR,
|
||||
TeamMemberRole.OWNER,
|
||||
)
|
||||
collectionsOfTeam(
|
||||
@Args({ name: 'teamID', description: 'ID of the team', type: () => ID })
|
||||
teamID: string,
|
||||
@Args({
|
||||
name: 'cursor',
|
||||
type: () => ID,
|
||||
nullable: true,
|
||||
description: 'ID of the last returned collection (for pagination)',
|
||||
})
|
||||
cursor?: string,
|
||||
): Promise<TeamCollection[]> {
|
||||
return this.teamCollectionService.getTeamCollections(
|
||||
teamID,
|
||||
cursor ?? null,
|
||||
async rootCollectionsOfTeam(@Args() args: GetRootTeamCollectionsArgs) {
|
||||
return this.teamCollectionService.getTeamRootCollections(
|
||||
args.teamID,
|
||||
args.cursor,
|
||||
args.take,
|
||||
);
|
||||
}
|
||||
|
||||
@Query(() => TeamCollection, {
|
||||
description: 'Get a collection with the given ID or null (if not exists)',
|
||||
description: 'Get a Team Collection with ID or null (if not exists)',
|
||||
nullable: true,
|
||||
})
|
||||
@UseGuards(GqlAuthGuard, GqlCollectionTeamMemberGuard)
|
||||
@@ -144,15 +125,20 @@ export class TeamCollectionResolver {
|
||||
TeamMemberRole.EDITOR,
|
||||
TeamMemberRole.OWNER,
|
||||
)
|
||||
collection(
|
||||
async collection(
|
||||
@Args({
|
||||
name: 'collectionID',
|
||||
description: 'ID of the collection',
|
||||
type: () => ID,
|
||||
})
|
||||
collectionID: string,
|
||||
): Promise<TeamCollection | null> {
|
||||
return this.teamCollectionService.getCollection(collectionID);
|
||||
) {
|
||||
const teamCollections = await this.teamCollectionService.getCollection(
|
||||
collectionID,
|
||||
);
|
||||
|
||||
if (E.isLeft(teamCollections)) throwErr(teamCollections.left);
|
||||
return teamCollections.right;
|
||||
}
|
||||
|
||||
// Mutations
|
||||
@@ -162,13 +148,264 @@ export class TeamCollectionResolver {
|
||||
})
|
||||
@UseGuards(GqlAuthGuard, GqlTeamMemberGuard)
|
||||
@RequiresTeamRole(TeamMemberRole.OWNER, TeamMemberRole.EDITOR)
|
||||
createRootCollection(
|
||||
@Args({ name: 'teamID', description: 'ID of the team', type: () => ID })
|
||||
async createRootCollection(@Args() args: CreateRootTeamCollectionArgs) {
|
||||
const teamCollection = await this.teamCollectionService.createCollection(
|
||||
args.teamID,
|
||||
args.title,
|
||||
null,
|
||||
);
|
||||
|
||||
if (E.isLeft(teamCollection)) throwErr(teamCollection.left);
|
||||
return teamCollection.right;
|
||||
}
|
||||
|
||||
@Mutation(() => Boolean, {
|
||||
description: 'Import collections from JSON string to the specified Team',
|
||||
})
|
||||
@UseGuards(GqlAuthGuard, GqlTeamMemberGuard)
|
||||
@RequiresTeamRole(TeamMemberRole.OWNER, TeamMemberRole.EDITOR)
|
||||
async importCollectionsFromJSON(
|
||||
@Args({
|
||||
name: 'teamID',
|
||||
type: () => ID,
|
||||
description: 'Id of the team to add to',
|
||||
})
|
||||
teamID: string,
|
||||
@Args({ name: 'title', description: 'Title of the new collection' })
|
||||
title: string,
|
||||
): Promise<TeamCollection> {
|
||||
return this.teamCollectionService.createCollection(teamID, title, null);
|
||||
@Args({
|
||||
name: 'jsonString',
|
||||
description: 'JSON string to import',
|
||||
})
|
||||
jsonString: string,
|
||||
@Args({
|
||||
name: 'parentCollectionID',
|
||||
type: () => ID,
|
||||
description:
|
||||
'ID to the collection to which to import to (null if to import to the root of team)',
|
||||
nullable: true,
|
||||
})
|
||||
parentCollectionID?: string,
|
||||
): Promise<boolean> {
|
||||
const importedCollection =
|
||||
await this.teamCollectionService.importCollectionsFromJSON(
|
||||
jsonString,
|
||||
teamID,
|
||||
parentCollectionID ?? null,
|
||||
);
|
||||
if (E.isLeft(importedCollection)) throwErr(importedCollection.left);
|
||||
return importedCollection.right;
|
||||
}
|
||||
|
||||
@Mutation(() => Boolean, {
|
||||
description:
|
||||
'Replace existing collections of a specific team with collections in JSON string',
|
||||
})
|
||||
@UseGuards(GqlAuthGuard, GqlTeamMemberGuard)
|
||||
@RequiresTeamRole(TeamMemberRole.OWNER, TeamMemberRole.EDITOR)
|
||||
async replaceCollectionsWithJSON(@Args() args: ReplaceTeamCollectionArgs) {
|
||||
const teamCollection =
|
||||
await this.teamCollectionService.replaceCollectionsWithJSON(
|
||||
args.jsonString,
|
||||
args.teamID,
|
||||
args.parentCollectionID ?? null,
|
||||
);
|
||||
|
||||
if (E.isLeft(teamCollection)) throwErr(teamCollection.left);
|
||||
return teamCollection.right;
|
||||
}
|
||||
|
||||
@Mutation(() => TeamCollection, {
|
||||
description: 'Create a collection that has a parent collection',
|
||||
})
|
||||
@UseGuards(GqlAuthGuard, GqlCollectionTeamMemberGuard)
|
||||
@RequiresTeamRole(TeamMemberRole.OWNER, TeamMemberRole.EDITOR)
|
||||
async createChildCollection(@Args() args: CreateChildTeamCollectionArgs) {
|
||||
const team = await this.teamCollectionService.getTeamOfCollection(
|
||||
args.collectionID,
|
||||
);
|
||||
if (E.isLeft(team)) throwErr(team.left);
|
||||
|
||||
const teamCollection = await this.teamCollectionService.createCollection(
|
||||
team.right.id,
|
||||
args.childTitle,
|
||||
args.collectionID,
|
||||
);
|
||||
|
||||
if (E.isLeft(teamCollection)) throwErr(teamCollection.left);
|
||||
return teamCollection.right;
|
||||
}
|
||||
|
||||
@Mutation(() => TeamCollection, {
|
||||
description: 'Rename a collection',
|
||||
})
|
||||
@UseGuards(GqlAuthGuard, GqlCollectionTeamMemberGuard)
|
||||
@RequiresTeamRole(TeamMemberRole.OWNER, TeamMemberRole.EDITOR)
|
||||
async renameCollection(@Args() args: RenameTeamCollectionArgs) {
|
||||
const updatedTeamCollection =
|
||||
await this.teamCollectionService.renameCollection(
|
||||
args.collectionID,
|
||||
args.newTitle,
|
||||
);
|
||||
|
||||
if (E.isLeft(updatedTeamCollection)) throwErr(updatedTeamCollection.left);
|
||||
return updatedTeamCollection.right;
|
||||
}
|
||||
|
||||
@Mutation(() => Boolean, {
|
||||
description: 'Delete a collection',
|
||||
})
|
||||
@UseGuards(GqlAuthGuard, GqlCollectionTeamMemberGuard)
|
||||
@RequiresTeamRole(TeamMemberRole.OWNER, TeamMemberRole.EDITOR)
|
||||
async deleteCollection(
|
||||
@Args({
|
||||
name: 'collectionID',
|
||||
description: 'ID of the collection',
|
||||
type: () => ID,
|
||||
})
|
||||
collectionID: string,
|
||||
) {
|
||||
const result = await this.teamCollectionService.deleteCollection(
|
||||
collectionID,
|
||||
);
|
||||
|
||||
if (E.isLeft(result)) throwErr(result.left);
|
||||
return result.right;
|
||||
}
|
||||
|
||||
@Mutation(() => TeamCollection, {
|
||||
description:
|
||||
'Move a collection into a new parent collection or the root of the team',
|
||||
})
|
||||
@UseGuards(GqlAuthGuard, GqlCollectionTeamMemberGuard)
|
||||
@RequiresTeamRole(TeamMemberRole.OWNER, TeamMemberRole.EDITOR)
|
||||
async moveCollection(@Args() args: MoveTeamCollectionArgs) {
|
||||
const res = await this.teamCollectionService.moveCollection(
|
||||
args.collectionID,
|
||||
args.parentCollectionID,
|
||||
);
|
||||
if (E.isLeft(res)) throwErr(res.left);
|
||||
return res.right;
|
||||
}
|
||||
|
||||
@Mutation(() => Boolean, {
|
||||
description: 'Update the order of collections',
|
||||
})
|
||||
@UseGuards(GqlAuthGuard, GqlCollectionTeamMemberGuard)
|
||||
@RequiresTeamRole(TeamMemberRole.OWNER, TeamMemberRole.EDITOR)
|
||||
async updateCollectionOrder(@Args() args: UpdateTeamCollectionOrderArgs) {
|
||||
const request = await this.teamCollectionService.updateCollectionOrder(
|
||||
args.collectionID,
|
||||
args.destCollID,
|
||||
);
|
||||
if (E.isLeft(request)) throwErr(request.left);
|
||||
return request.right;
|
||||
}
|
||||
|
||||
// Subscriptions
|
||||
|
||||
@Subscription(() => TeamCollection, {
|
||||
description:
|
||||
'Listen to when a collection has been added to a team. The emitted value is the team added',
|
||||
resolve: (value) => value,
|
||||
})
|
||||
@RequiresTeamRole(
|
||||
TeamMemberRole.OWNER,
|
||||
TeamMemberRole.EDITOR,
|
||||
TeamMemberRole.VIEWER,
|
||||
)
|
||||
@UseGuards(GqlAuthGuard, GqlTeamMemberGuard)
|
||||
teamCollectionAdded(
|
||||
@Args({
|
||||
name: 'teamID',
|
||||
description: 'ID of the team to listen to',
|
||||
type: () => ID,
|
||||
})
|
||||
teamID: string,
|
||||
) {
|
||||
return this.pubsub.asyncIterator(`team_coll/${teamID}/coll_added`);
|
||||
}
|
||||
|
||||
@Subscription(() => TeamCollection, {
|
||||
description: 'Listen to when a collection has been updated.',
|
||||
resolve: (value) => value,
|
||||
})
|
||||
@RequiresTeamRole(
|
||||
TeamMemberRole.OWNER,
|
||||
TeamMemberRole.EDITOR,
|
||||
TeamMemberRole.VIEWER,
|
||||
)
|
||||
@UseGuards(GqlAuthGuard, GqlTeamMemberGuard)
|
||||
teamCollectionUpdated(
|
||||
@Args({
|
||||
name: 'teamID',
|
||||
description: 'ID of the team to listen to',
|
||||
type: () => ID,
|
||||
})
|
||||
teamID: string,
|
||||
) {
|
||||
return this.pubsub.asyncIterator(`team_coll/${teamID}/coll_updated`);
|
||||
}
|
||||
|
||||
@Subscription(() => ID, {
|
||||
description: 'Listen to when a collection has been removed',
|
||||
resolve: (value) => value,
|
||||
})
|
||||
@RequiresTeamRole(
|
||||
TeamMemberRole.OWNER,
|
||||
TeamMemberRole.EDITOR,
|
||||
TeamMemberRole.VIEWER,
|
||||
)
|
||||
@UseGuards(GqlAuthGuard, GqlTeamMemberGuard)
|
||||
teamCollectionRemoved(
|
||||
@Args({
|
||||
name: 'teamID',
|
||||
description: 'ID of the team to listen to',
|
||||
type: () => ID,
|
||||
})
|
||||
teamID: string,
|
||||
) {
|
||||
return this.pubsub.asyncIterator(`team_coll/${teamID}/coll_removed`);
|
||||
}
|
||||
|
||||
@Subscription(() => TeamCollection, {
|
||||
description: 'Listen to when a collection has been moved',
|
||||
resolve: (value) => value,
|
||||
})
|
||||
@RequiresTeamRole(
|
||||
TeamMemberRole.OWNER,
|
||||
TeamMemberRole.EDITOR,
|
||||
TeamMemberRole.VIEWER,
|
||||
)
|
||||
@UseGuards(GqlAuthGuard, GqlTeamMemberGuard)
|
||||
teamCollectionMoved(
|
||||
@Args({
|
||||
name: 'teamID',
|
||||
description: 'ID of the team to listen to',
|
||||
type: () => ID,
|
||||
})
|
||||
teamID: string,
|
||||
) {
|
||||
return this.pubsub.asyncIterator(`team_coll/${teamID}/coll_moved`);
|
||||
}
|
||||
|
||||
@Subscription(() => CollectionReorderData, {
|
||||
description: 'Listen to when a collections position has changed',
|
||||
resolve: (value) => value,
|
||||
})
|
||||
@RequiresTeamRole(
|
||||
TeamMemberRole.OWNER,
|
||||
TeamMemberRole.EDITOR,
|
||||
TeamMemberRole.VIEWER,
|
||||
)
|
||||
@UseGuards(GqlAuthGuard, GqlTeamMemberGuard)
|
||||
collectionOrderUpdated(
|
||||
@Args({
|
||||
name: 'teamID',
|
||||
description: 'ID of the team to listen to',
|
||||
type: () => ID,
|
||||
})
|
||||
teamID: string,
|
||||
) {
|
||||
return this.pubsub.asyncIterator(`team_coll/${teamID}/coll_order_updated`);
|
||||
}
|
||||
|
||||
// @Mutation(() => TeamCollection, {
|
||||
@@ -214,204 +451,4 @@ export class TeamCollectionResolver {
|
||||
// );
|
||||
// }
|
||||
// }
|
||||
|
||||
// @Mutation(() => Boolean, {
|
||||
// description: 'Import collections from JSON string to the specified Team',
|
||||
// })
|
||||
// @UseGuards(GqlAuthGuard, GqlTeamMemberGuard)
|
||||
// @RequiresTeamRole(TeamMemberRole.OWNER, TeamMemberRole.EDITOR)
|
||||
// async importCollectionsFromJSON(
|
||||
// @Args({
|
||||
// name: 'teamID',
|
||||
// type: () => ID,
|
||||
// description: 'Id of the team to add to',
|
||||
// })
|
||||
// teamID: string,
|
||||
// @Args({
|
||||
// name: 'jsonString',
|
||||
// description: 'JSON string to import',
|
||||
// })
|
||||
// jsonString: string,
|
||||
// @Args({
|
||||
// name: 'parentCollectionID',
|
||||
// type: () => ID,
|
||||
// description:
|
||||
// 'ID to the collection to which to import to (null if to import to the root of team)',
|
||||
// nullable: true,
|
||||
// })
|
||||
// parentCollectionID?: string,
|
||||
// ): Promise<boolean> {
|
||||
// await this.teamCollectionService.importCollectionsFromJSON(
|
||||
// jsonString,
|
||||
// teamID,
|
||||
// parentCollectionID ?? null,
|
||||
// );
|
||||
|
||||
// return true;
|
||||
// }
|
||||
|
||||
// @Mutation(() => Boolean, {
|
||||
// description:
|
||||
// 'Replace existing collections of a specific team with collections in JSON string',
|
||||
// })
|
||||
// @UseGuards(GqlAuthGuard, GqlTeamMemberGuard)
|
||||
// @RequiresTeamRole(TeamMemberRole.OWNER, TeamMemberRole.EDITOR)
|
||||
// async replaceCollectionsWithJSON(
|
||||
// @Args({
|
||||
// name: 'teamID',
|
||||
// type: () => ID,
|
||||
// description: 'Id of the team to add to',
|
||||
// })
|
||||
// teamID: string,
|
||||
// @Args({
|
||||
// name: 'jsonString',
|
||||
// description: 'JSON string to replace with',
|
||||
// })
|
||||
// jsonString: string,
|
||||
// @Args({
|
||||
// name: 'parentCollectionID',
|
||||
// type: () => ID,
|
||||
// description:
|
||||
// 'ID to the collection to which to import to (null if to import to the root of team)',
|
||||
// nullable: true,
|
||||
// })
|
||||
// parentCollectionID?: string,
|
||||
// ): Promise<boolean> {
|
||||
// await this.teamCollectionService.replaceCollectionsWithJSON(
|
||||
// jsonString,
|
||||
// teamID,
|
||||
// parentCollectionID ?? null,
|
||||
// );
|
||||
|
||||
// return true;
|
||||
// }
|
||||
|
||||
@Mutation(() => TeamCollection, {
|
||||
description: 'Create a collection that has a parent collection',
|
||||
})
|
||||
@UseGuards(GqlAuthGuard, GqlCollectionTeamMemberGuard)
|
||||
@RequiresTeamRole(TeamMemberRole.OWNER, TeamMemberRole.EDITOR)
|
||||
async createChildCollection(
|
||||
@Args({
|
||||
name: 'collectionID',
|
||||
type: () => ID,
|
||||
description: 'ID of the parent to the new collection',
|
||||
})
|
||||
collectionID: string,
|
||||
@Args({ name: 'childTitle', description: 'Title of the new collection' })
|
||||
childTitle: string,
|
||||
): Promise<TeamCollection> {
|
||||
const team = await this.teamCollectionService.getTeamOfCollection(
|
||||
collectionID,
|
||||
);
|
||||
return await this.teamCollectionService.createCollection(
|
||||
team.id,
|
||||
childTitle,
|
||||
collectionID,
|
||||
);
|
||||
}
|
||||
|
||||
@Mutation(() => TeamCollection, {
|
||||
description: 'Rename a collection',
|
||||
})
|
||||
@UseGuards(GqlAuthGuard, GqlCollectionTeamMemberGuard)
|
||||
@RequiresTeamRole(TeamMemberRole.OWNER, TeamMemberRole.EDITOR)
|
||||
renameCollection(
|
||||
@Args({
|
||||
name: 'collectionID',
|
||||
description: 'ID of the collection',
|
||||
type: () => ID,
|
||||
})
|
||||
collectionID: string,
|
||||
@Args({
|
||||
name: 'newTitle',
|
||||
description: 'The updated title of the collection',
|
||||
})
|
||||
newTitle: string,
|
||||
): Promise<TeamCollection> {
|
||||
return this.teamCollectionService.renameCollection(collectionID, newTitle);
|
||||
}
|
||||
|
||||
@Mutation(() => Boolean, {
|
||||
description: 'Delete a collection',
|
||||
})
|
||||
@UseGuards(GqlAuthGuard, GqlCollectionTeamMemberGuard)
|
||||
@RequiresTeamRole(TeamMemberRole.OWNER, TeamMemberRole.EDITOR)
|
||||
async deleteCollection(
|
||||
@Args({
|
||||
name: 'collectionID',
|
||||
description: 'ID of the collection',
|
||||
type: () => ID,
|
||||
})
|
||||
collectionID: string,
|
||||
): Promise<boolean> {
|
||||
this.teamCollectionService.deleteCollection(collectionID);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
// Subscriptions
|
||||
@Subscription(() => TeamCollection, {
|
||||
description:
|
||||
'Listen to when a collection has been added to a team. The emitted value is the team added',
|
||||
resolve: (value) => value,
|
||||
})
|
||||
@RequiresTeamRole(
|
||||
TeamMemberRole.OWNER,
|
||||
TeamMemberRole.EDITOR,
|
||||
TeamMemberRole.VIEWER,
|
||||
)
|
||||
@UseGuards(GqlAuthGuard, GqlTeamMemberGuard)
|
||||
teamCollectionAdded(
|
||||
@Args({
|
||||
name: 'teamID',
|
||||
description: 'ID of the team to listen to',
|
||||
type: () => ID,
|
||||
})
|
||||
teamID: string,
|
||||
): AsyncIterator<TeamCollection> {
|
||||
return this.pubsub.asyncIterator(`team_coll/${teamID}/coll_added`);
|
||||
}
|
||||
|
||||
@Subscription(() => TeamCollection, {
|
||||
description: 'Listen to when a collection has been updated.',
|
||||
resolve: (value) => value,
|
||||
})
|
||||
@RequiresTeamRole(
|
||||
TeamMemberRole.OWNER,
|
||||
TeamMemberRole.EDITOR,
|
||||
TeamMemberRole.VIEWER,
|
||||
)
|
||||
@UseGuards(GqlAuthGuard, GqlTeamMemberGuard)
|
||||
teamCollectionUpdated(
|
||||
@Args({
|
||||
name: 'teamID',
|
||||
description: 'ID of the team to listen to',
|
||||
type: () => ID,
|
||||
})
|
||||
teamID: string,
|
||||
): AsyncIterator<TeamCollection> {
|
||||
return this.pubsub.asyncIterator(`team_coll/${teamID}/coll_updated`);
|
||||
}
|
||||
|
||||
@Subscription(() => ID, {
|
||||
description: 'Listen to when a collection has been removed',
|
||||
resolve: (value) => value,
|
||||
})
|
||||
@RequiresTeamRole(
|
||||
TeamMemberRole.OWNER,
|
||||
TeamMemberRole.EDITOR,
|
||||
TeamMemberRole.VIEWER,
|
||||
)
|
||||
@UseGuards(GqlAuthGuard, GqlTeamMemberGuard)
|
||||
teamCollectionRemoved(
|
||||
@Args({
|
||||
name: 'teamID',
|
||||
description: 'ID of the team to listen to',
|
||||
type: () => ID,
|
||||
})
|
||||
teamID: string,
|
||||
): AsyncIterator<TeamCollection> {
|
||||
return this.pubsub.asyncIterator(`team_coll/${teamID}/coll_removed`);
|
||||
}
|
||||
}
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
Reference in New Issue
Block a user