Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(course-users): add activist role #2282

Merged
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
Loading