Skip to content

Commit

Permalink
feat(course-users): add activist role (#2282)
Browse files Browse the repository at this point in the history
* feat(course-users): add isActivist to CourseUser model, add migration

* feat(course-users): add isActivist to dtos, update user activist field too

* feat(api): update openapi

* feat(course-users): add activist to CourseRole enum, update openapi

* feat(course-users): add Activist to columns and to form

* fix(course-users): update test with isActivist field

* fix(course-users): formatting
  • Loading branch information
ThorsAngerVaNeT authored Sep 10, 2023
1 parent 292c27e commit 72cf45c
Show file tree
Hide file tree
Showing 12 changed files with 109 additions and 17 deletions.
27 changes: 24 additions & 3 deletions client/src/api/api.ts
Original file line number Diff line number Diff line change
Expand Up @@ -925,6 +925,12 @@ export interface CourseRolesDto {
* @memberof CourseRolesDto
*/
'isDementor': boolean;
/**
*
* @type {boolean}
* @memberof CourseRolesDto
*/
'isActivist': boolean;
}
/**
*
Expand Down Expand Up @@ -1424,6 +1430,12 @@ export interface CourseUserDto {
* @memberof CourseUserDto
*/
'isDementor': boolean;
/**
*
* @type {boolean}
* @memberof CourseUserDto
*/
'isActivist': boolean;
}
/**
*
Expand Down Expand Up @@ -2054,7 +2066,8 @@ export const CreateUserGroupDtoRolesEnum = {
Supervisor: 'supervisor',
Student: 'student',
Mentor: 'mentor',
Dementor: 'dementor'
Dementor: 'dementor',
Activist: 'activist'
} as const;

export type CreateUserGroupDtoRolesEnum = typeof CreateUserGroupDtoRolesEnum[keyof typeof CreateUserGroupDtoRolesEnum];
Expand Down Expand Up @@ -5869,6 +5882,12 @@ export interface UpdateCourseUserDto {
* @memberof UpdateCourseUserDto
*/
'isDementor': boolean;
/**
*
* @type {boolean}
* @memberof UpdateCourseUserDto
*/
'isActivist': boolean;
/**
*
* @type {number}
Expand Down Expand Up @@ -6537,7 +6556,8 @@ export const UpdateUserGroupDtoRolesEnum = {
Supervisor: 'supervisor',
Student: 'student',
Mentor: 'mentor',
Dementor: 'dementor'
Dementor: 'dementor',
Activist: 'activist'
} as const;

export type UpdateUserGroupDtoRolesEnum = typeof UpdateUserGroupDtoRolesEnum[keyof typeof UpdateUserGroupDtoRolesEnum];
Expand Down Expand Up @@ -6655,7 +6675,8 @@ export const UserGroupDtoRolesEnum = {
Supervisor: 'supervisor',
Student: 'student',
Mentor: 'mentor',
Dementor: 'dementor'
Dementor: 'dementor',
Activist: 'activist'
} as const;

export type UserGroupDtoRolesEnum = typeof UserGroupDtoRolesEnum[keyof typeof UserGroupDtoRolesEnum];
Expand Down
14 changes: 13 additions & 1 deletion client/src/pages/course/admin/users.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -111,6 +111,11 @@ function Page() {
<Checkbox>Dementor</Checkbox>
</Form.Item>
</Col>
<Col span={8}>
<Form.Item name="isActivist" valuePropName="checked">
<Checkbox>Activist</Checkbox>
</Form.Item>
</Col>
</Row>
</ModalForm>
);
Expand Down Expand Up @@ -225,6 +230,11 @@ function getColumns(handleEditItem: any) {
dataIndex: 'isDementor',
render: boolIconRenderer,
},
{
title: 'Activist',
dataIndex: 'isActivist',
render: boolIconRenderer,
},
{
title: 'Actions',
dataIndex: 'actions',
Expand All @@ -242,6 +252,7 @@ function createRecord(values: any) {
isManager: values.isManager,
isSupervisor: values.isSupervisor,
isDementor: values.isDementor,
isActivist: values.isActivist,
};
return data;
}
Expand All @@ -254,10 +265,11 @@ function createRecords(groups: UserGroupDto[]) {
users[id].isManager = users[id].isManager || group.roles.includes(CourseRole.Manager);
users[id].isSupervisor = users[id].isSupervisor || group.roles.includes(CourseRole.Supervisor);
users[id].isDementor = users[id].isDementor || group.roles.includes(CourseRole.Dementor);
users[id].isActivist = users[id].isActivist || group.roles.includes(CourseRole.Activist);
});
return users;
},
{} as Record<string, { isManager: boolean; isSupervisor: boolean; isDementor: boolean }>,
{} as Record<string, { isManager: boolean; isSupervisor: boolean; isDementor: boolean; isActivist: boolean }>,
);
return Object.entries(data).map(([id, roles]) => ({ ...roles, userId: Number(id) }));
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ const mockCourseUser = {
isSupervisor: true,
isJuryActivist: false,
isDementor: true,
isActivist: false,
githubId: mockGithubId,
name: 'Foo Bar',
} as ExtendedCourseUser;
Expand Down Expand Up @@ -82,14 +83,15 @@ describe('CourseUsersController', () => {

await controller.putUser(mockCourseId, mockGithubId, mockCourseUser);

const { isManager, isDementor, isSupervisor } = mockCourseUser;
const { isManager, isDementor, isSupervisor, isActivist } = mockCourseUser;

expect(mockUsersService.getByGithubId).toHaveBeenCalledWith(mockGithubId);
expect(mockCourseUsersService.getByUserId).toHaveBeenCalledWith(mockUserId, mockCourseId);
expect(mockCourseUsersService.updateCourseUser).toHaveBeenCalledWith(mockUserId, {
isDementor,
isManager,
isSupervisor,
isActivist,
});
expect(mockCourseUsersService.saveCourseUsers).not.toHaveBeenCalled();
});
Expand All @@ -100,7 +102,7 @@ describe('CourseUsersController', () => {

await controller.putUser(mockCourseId, mockGithubId, mockCourseUser);

const { isManager, isDementor, isSupervisor } = mockCourseUser;
const { isManager, isDementor, isSupervisor, isActivist } = mockCourseUser;

expect(mockUsersService.getByGithubId).toHaveBeenCalledWith(mockGithubId);
expect(mockCourseUsersService.getByUserId).toHaveBeenCalledWith(mockUserId, mockCourseId);
Expand All @@ -110,6 +112,7 @@ describe('CourseUsersController', () => {
isDementor,
isManager,
isSupervisor,
isActivist,
});
expect(mockCourseUsersService.updateCourseUser).not.toHaveBeenCalled();
});
Expand Down
16 changes: 13 additions & 3 deletions nestjs/src/courses/course-users/course-users.controller.ts
Original file line number Diff line number Diff line change
Expand Up @@ -73,13 +73,23 @@ export class CourseUsersController {
throw new BadRequestException(`User with githubid ${githubId} is not found`);
}

const { isManager = false, isSupervisor = false, isDementor = false } = roles;
const { isManager = false, isSupervisor = false, isDementor = false, isActivist = false } = roles;
const courseUser = await this.courseUserService.getByUserId(user.id, courseId);
if (isActivist) {
this.usersService.updateUser(user.id, { activist: isActivist });
}

if (!courseUser) {
await this.courseUserService.saveCourseUsers({ courseId, userId: user.id, isManager, isSupervisor, isDementor });
await this.courseUserService.saveCourseUsers({
courseId,
userId: user.id,
isManager,
isSupervisor,
isDementor,
isActivist,
});
} else {
await this.courseUserService.updateCourseUser(courseUser.id, { isManager, isSupervisor, isDementor });
await this.courseUserService.updateCourseUser(courseUser.id, { isManager, isSupervisor, isDementor, isActivist });
}
}
}
4 changes: 4 additions & 0 deletions nestjs/src/courses/course-users/course-users.service.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ const mockCourseUser = {
isSupervisor: true,
isJuryActivist: false,
isDementor: true,
isActivist: true,
user: {
id: mockUserId,
firstName: ' Foo ',
Expand All @@ -37,6 +38,7 @@ const mockUsersToInsert = [
isDementor: true,
isManager: true,
isSupervisor: true,
isActivist: false,
},
];
const mockUsersToUpdate = [
Expand All @@ -45,12 +47,14 @@ const mockUsersToUpdate = [
isDementor: true,
isManager: false,
isSupervisor: true,
isActivist: true,
},
{
userId: mockUserId2,
isDementor: true,
isManager: true,
isSupervisor: true,
isActivist: false,
},
];

Expand Down
5 changes: 5 additions & 0 deletions nestjs/src/courses/course-users/dto/course-roles.dto.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,4 +16,9 @@ export class CourseRolesDto {
@IsBoolean()
@ApiProperty()
isDementor: boolean;

@IsOptional()
@IsBoolean()
@ApiProperty()
isActivist: boolean;
}
5 changes: 5 additions & 0 deletions nestjs/src/courses/course-users/dto/course-user.dto.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ export class CourseUserDto {
this.isSupervisor = courseUser.isSupervisor;
this.isJuryActivist = courseUser.isJuryActivist;
this.isDementor = courseUser.isDementor;
this.isActivist = courseUser.isActivist;
}

@IsNotEmpty()
Expand Down Expand Up @@ -47,4 +48,8 @@ export class CourseUserDto {
@IsBoolean()
@ApiProperty()
isDementor: boolean;

@IsBoolean()
@ApiProperty()
isActivist: boolean;
}
29 changes: 21 additions & 8 deletions nestjs/src/spec.json
Original file line number Diff line number Diff line change
Expand Up @@ -3433,28 +3433,41 @@
"isManager": { "type": "boolean" },
"isSupervisor": { "type": "boolean" },
"isJuryActivist": { "type": "boolean" },
"isDementor": { "type": "boolean" }
"isDementor": { "type": "boolean" },
"isActivist": { "type": "boolean" }
},
"required": ["id", "courseId", "name", "githubId", "isManager", "isSupervisor", "isJuryActivist", "isDementor"]
"required": [
"id",
"courseId",
"name",
"githubId",
"isManager",
"isSupervisor",
"isJuryActivist",
"isDementor",
"isActivist"
]
},
"UpdateCourseUserDto": {
"type": "object",
"properties": {
"isManager": { "type": "boolean" },
"isSupervisor": { "type": "boolean" },
"isDementor": { "type": "boolean" },
"isActivist": { "type": "boolean" },
"userId": { "type": "number" }
},
"required": ["isManager", "isSupervisor", "isDementor", "userId"]
"required": ["isManager", "isSupervisor", "isDementor", "isActivist", "userId"]
},
"CourseRolesDto": {
"type": "object",
"properties": {
"isManager": { "type": "boolean" },
"isSupervisor": { "type": "boolean" },
"isDementor": { "type": "boolean" }
"isDementor": { "type": "boolean" },
"isActivist": { "type": "boolean" }
},
"required": ["isManager", "isSupervisor", "isDementor"]
"required": ["isManager", "isSupervisor", "isDementor", "isActivist"]
},
"StudentId": { "type": "object", "properties": { "id": { "type": "number" } }, "required": ["id"] },
"MentorDetailsDto": {
Expand Down Expand Up @@ -4232,7 +4245,7 @@
"type": "array",
"items": {
"type": "string",
"enum": ["taskOwner", "manager", "supervisor", "student", "mentor", "dementor"]
"enum": ["taskOwner", "manager", "supervisor", "student", "mentor", "dementor", "activist"]
}
}
},
Expand All @@ -4253,7 +4266,7 @@
"type": "array",
"items": {
"type": "string",
"enum": ["taskOwner", "manager", "supervisor", "student", "mentor", "dementor"]
"enum": ["taskOwner", "manager", "supervisor", "student", "mentor", "dementor", "activist"]
}
}
},
Expand All @@ -4268,7 +4281,7 @@
"type": "array",
"items": {
"type": "string",
"enum": ["taskOwner", "manager", "supervisor", "student", "mentor", "dementor"]
"enum": ["taskOwner", "manager", "supervisor", "student", "mentor", "dementor", "activist"]
}
}
},
Expand Down
13 changes: 13 additions & 0 deletions server/src/migrations/1693930286280-CourseUsersActivist.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
import { MigrationInterface, QueryRunner } from 'typeorm';

export class CourseUsersActivist1693930286280 implements MigrationInterface {
name = 'CourseUsersActivist1693930286280';

public async up(queryRunner: QueryRunner): Promise<void> {
await queryRunner.query(`ALTER TABLE "course_user" ADD "isActivist" boolean NOT NULL DEFAULT false`);
}

public async down(queryRunner: QueryRunner): Promise<void> {
await queryRunner.query(`ALTER TABLE "course_user" DROP COLUMN "isActivist"`);
}
}
2 changes: 2 additions & 0 deletions server/src/migrations/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,7 @@ import { Prompt1687009744110 } from './1687009744110-Prompt';
import { Temperature1691520611773 } from './1691520611773-Temperature';
import { Temperature1691524327332 } from './1691524327332-Temperature';
import { InterviewScore1686657350908 } from './1686657350908-InterviewScore';
import { CourseUsersActivist1693930286280 } from './1693930286280-CourseUsersActivist';

export const migrations = [
UserMigration1630340371992,
Expand Down Expand Up @@ -106,4 +107,5 @@ export const migrations = [
Temperature1691520611773,
Temperature1691524327332,
InterviewScore1686657350908,
CourseUsersActivist1693930286280,
];
3 changes: 3 additions & 0 deletions server/src/models/courseUser.ts
Original file line number Diff line number Diff line change
Expand Up @@ -37,4 +37,7 @@ export class CourseUser {

@Column({ default: false })
isDementor: boolean;

@Column({ default: false })
isActivist: boolean;
}
1 change: 1 addition & 0 deletions server/src/models/session.ts
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ export enum CourseRole {
Student = 'student',
Mentor = 'mentor',
Dementor = 'dementor',
Activist = 'activist',
}

function hasRole(user?: IUserSession, courseId?: number, role?: CourseRole) {
Expand Down

0 comments on commit 72cf45c

Please sign in to comment.