Skip to content

Commit 6faa9ac

Browse files
committed
refactor: move selected view logic to backend
1 parent e43ccd9 commit 6faa9ac

5 files changed

Lines changed: 67 additions & 142 deletions

File tree

HwProj.APIGateway/HwProj.APIGateway.API/Controllers/CoursesController.cs

Lines changed: 56 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
using System.Collections.Generic;
22
using System.Linq;
3+
using System;
34
using System.Net;
45
using System.Threading.Tasks;
56
using AutoMapper;
@@ -269,16 +270,64 @@ public async Task<IActionResult> GetMentorWorkspace(long courseId, string mentor
269270
if (!mentorCourseView.Succeeded)
270271
return BadRequest(mentorCourseView.Errors[0]);
271272

272-
var studentIds = mentorCourseView.Value.CourseMates.Select(t => t.StudentId).ToArray();
273-
var students = await AuthServiceClient.GetAccountsData(studentIds);
273+
var courseResult = await _coursesClient.GetCourseDataRaw(courseId);
274+
if (!courseResult.Succeeded)
275+
return BadRequest(courseResult.Errors[0]);
276+
277+
var workspace = await CourseToMentorWorkspaceViewModel(courseResult.Value, mentorCourseView.Value);
278+
return Ok(workspace);
279+
}
274280

275-
var workspace = new WorkspaceViewModel
281+
private async Task<WorkspaceViewModel> CourseToMentorWorkspaceViewModel(CourseDTO course, CourseDTO mentorCourseView)
282+
{
283+
var courseGroups = (course.Groups ?? Array.Empty<GroupViewModel>())
284+
.Where(g => !string.IsNullOrWhiteSpace(g.Name))
285+
.ToArray();
286+
287+
var filteredGroups = (mentorCourseView.Groups ?? Array.Empty<GroupViewModel>())
288+
.Where(g => !string.IsNullOrWhiteSpace(g.Name))
289+
.ToArray();
290+
291+
var selectedGroups = filteredGroups.Length == courseGroups.Length
292+
? Array.Empty<GroupViewModel>()
293+
: filteredGroups;
294+
295+
var selectedGroupsStudentIds = selectedGroups
296+
.SelectMany(g => g.StudentsIds ?? Array.Empty<string>())
297+
.ToHashSet();
298+
299+
var selectedStudentIdsWithoutGroups = (mentorCourseView.CourseMates ?? Array.Empty<CourseMateViewModel>())
300+
.Select(t => t.StudentId)
301+
.Where(studentId => !selectedGroupsStudentIds.Contains(studentId))
302+
.ToArray();
303+
304+
var selectedStudentsData = selectedStudentIdsWithoutGroups.Length == (course.CourseMates?.Length ?? 0)
305+
? Array.Empty<AccountDataDto>()
306+
: await AuthServiceClient.GetAccountsData(selectedStudentIdsWithoutGroups);
307+
308+
var selectedStudents = selectedStudentsData
309+
.Where(x => x != null)
310+
.OrderBy(x => x.Surname)
311+
.ThenBy(x => x.Name)
312+
.ToArray();
313+
314+
var availableHomeworks = selectedGroups.Any()
315+
? (course.Homeworks ?? Array.Empty<HomeworkViewModel>())
316+
.Where(h => h.GroupId == null || selectedGroups.Any(g => g.Id == h.GroupId))
317+
.ToArray()
318+
: course.Homeworks ?? Array.Empty<HomeworkViewModel>();
319+
320+
var filteredHomeworks = mentorCourseView.Homeworks ?? Array.Empty<HomeworkViewModel>();
321+
var selectedHomeworks = filteredHomeworks.Length == availableHomeworks.Length
322+
? Array.Empty<HomeworkViewModel>()
323+
: filteredHomeworks;
324+
325+
return new WorkspaceViewModel
276326
{
277-
Homeworks = mentorCourseView.Value.Homeworks,
278-
Students = students.OrderBy(x => x.Surname).ThenBy(x => x.Name).ToArray(),
279-
Groups = mentorCourseView.Value.Groups,
327+
Homeworks = selectedHomeworks,
328+
Students = selectedStudents,
329+
Groups = selectedGroups,
280330
};
281-
return Ok(workspace);
282331
}
283332

284333
private async Task<CourseViewModel> ToCourseViewModel(CourseDTO course)

hwproj.front/src/components/Common/GroupSelector.tsx

Lines changed: 0 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,6 @@ interface GroupSelectorProps {
2323
onGroupsUpdate: () => Promise<void>,
2424
selectedGroupId?: number,
2525
choiceDisabled?: boolean,
26-
onCreateNewGroup?: (group: GroupViewModel) => Promise<void>,
2726
}
2827

2928
const GroupSelector: FC<GroupSelectorProps> = (props) => {
@@ -87,11 +86,6 @@ const GroupSelector: FC<GroupSelectorProps> = (props) => {
8786
groupMatesIds: formState.memberIds,
8887
courseId: props.courseId,
8988
});
90-
await props.onCreateNewGroup?.({
91-
id: groupId,
92-
name: formState.name.trim(),
93-
studentsIds: formState.memberIds,
94-
});
9589
await props.onGroupsUpdate();
9690
props.onGroupIdChange(groupId);
9791
}

hwproj.front/src/components/Courses/CourseFilter.tsx

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,6 @@ import ApiSingleton from "../../api/ApiSingleton";
77
import ErrorsHandler from "../Utils/ErrorsHandler";
88
import {DotLottieReact} from '@lottiefiles/dotlottie-react';
99
import Button from "@material-ui/core/Button";
10-
import {getSelectedCourseView} from "./MentorWorkspaceUtils";
1110

1211
interface ICourseFilterProps {
1312
courseId: number;
@@ -64,11 +63,14 @@ const CourseFilter: FC<ICourseFilterProps> = (props) => {
6463
const mentorWorkspace =
6564
await ApiSingleton.coursesApi.coursesGetMentorWorkspace(props.courseId, props.mentorId);
6665

67-
const selectedCourseView = getSelectedCourseView(course, mentorWorkspace);
68-
6966
setState(prevState => ({
7067
...prevState,
71-
...selectedCourseView,
68+
courseHomeworks: course.homeworks ?? [],
69+
courseStudents: course.acceptedStudents ?? [],
70+
courseGroups: course.groups?.filter(g => g.name?.trim()) ?? [],
71+
selectedHomeworks: mentorWorkspace.homeworks ?? [],
72+
selectedStudents: mentorWorkspace.students ?? [],
73+
selectedGroups: mentorWorkspace.groups ?? [],
7274
mentors: course.mentors!,
7375
assignedStudents: assignedStudents.filter(x => x.mentorId !== props.mentorId)
7476
}))

hwproj.front/src/components/Courses/MentorWorkspaceUtils.ts

Lines changed: 0 additions & 47 deletions
This file was deleted.

hwproj.front/src/components/Homeworks/CourseHomeworkExperimental.tsx

Lines changed: 5 additions & 78 deletions
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,6 @@ import {FC, useEffect, useState} from "react"
2222
import Utils from "services/Utils";
2323
import {
2424
HomeworkViewModel, ActionOptions, HomeworkTaskViewModel, PostTaskViewModel, AccountDataDto, GroupViewModel,
25-
WorkspaceViewModel, CourseViewModel
2625
} from "@/api";
2726
import ApiSingleton from "../../api/ApiSingleton";
2827
import Tags from "../Common/Tags";
@@ -46,7 +45,6 @@ import GroupIcon from '@mui/icons-material/Group';
4645
import AssignmentIcon from '@mui/icons-material/Assignment';
4746
import ErrorsHandler from "@/components/Utils/ErrorsHandler";
4847
import {enqueueSnackbar} from "notistack";
49-
import {getSelectedCourseView} from "../Courses/MentorWorkspaceUtils";
5048

5149
export interface HomeworkAndFilesInfo {
5250
homework: HomeworkViewModel & { isModified?: boolean },
@@ -129,29 +127,19 @@ const CourseHomeworkEditor: FC<{
129127
const [description, setDescription] = useState<string>(loadedHomework.description!)
130128
const [selectedGroupId, setSelectedGroupId] = useState(loadedHomework.groupId)
131129
const [courseStudents, setCourseStudents] = useState<AccountDataDto[]>([])
132-
const [course, setCourse] = useState<CourseViewModel | undefined>(undefined)
133-
const [mentorWorkspace, setMentorWorkspace] = useState<WorkspaceViewModel | undefined>(undefined)
134130
const [page, setPage] = useState<"homework" | "group">("homework")
135131

136132
useEffect(() => {
137-
const loadMentorWorkspace = async () => {
133+
const loadCourseStudents = async () => {
138134
try {
139-
const [courseData, mentorWorkspace] = await Promise.all([
140-
ApiSingleton.coursesApi.coursesGetAllCourseData(courseId),
141-
isNewHomework
142-
? ApiSingleton.coursesApi.coursesGetMentorWorkspace(courseId, props.mentorId)
143-
.catch(() => undefined)
144-
: Promise.resolve(undefined)
145-
]);
135+
const courseData = await ApiSingleton.coursesApi.coursesGetAllCourseData(courseId);
146136
setCourseStudents(courseData.course?.acceptedStudents || [])
147-
setCourse(courseData.course)
148-
setMentorWorkspace(mentorWorkspace)
149137
} catch (error) {
150138
console.error('Failed to load course data:', error)
151139
}
152140
}
153-
loadMentorWorkspace()
154-
}, [courseId, props.mentorId, isNewHomework])
141+
loadCourseStudents()
142+
}, [courseId])
155143

156144
const [hasErrors, setHasErrors] = useState<boolean>(false)
157145

@@ -242,62 +230,6 @@ const CourseHomeworkEditor: FC<{
242230
props.onUpdate({homework: loadedHomework, isDeleted: true})
243231
}
244232

245-
const updateMentorFilter = async (update: {
246-
newGroup?: GroupViewModel,
247-
newHomework?: HomeworkViewModel
248-
}) => {
249-
if (!course || !mentorWorkspace) return;
250-
251-
const {newGroup, newHomework} = update;
252-
const selectedCourseView = getSelectedCourseView(course, mentorWorkspace);
253-
let updatedGroups = selectedCourseView.selectedGroups;
254-
let updatedHomeworks = selectedCourseView.selectedHomeworks;
255-
let hasChanges = false;
256-
257-
if (newGroup?.id !== undefined &&
258-
selectedCourseView.selectedGroups.length > 0 &&
259-
!selectedCourseView.selectedGroups.some(g => g.id === newGroup.id)) {
260-
updatedGroups = [...selectedCourseView.selectedGroups, newGroup];
261-
hasChanges = true;
262-
}
263-
264-
if (newHomework?.id !== undefined &&
265-
selectedCourseView.selectedHomeworks.length > 0 &&
266-
!selectedCourseView.selectedHomeworks.some(h => h.id === newHomework.id)) {
267-
updatedHomeworks = [...selectedCourseView.selectedHomeworks, newHomework];
268-
hasChanges = true;
269-
}
270-
271-
setCourse(prev => prev ? ({
272-
...prev,
273-
groups: newGroup?.id !== undefined && !prev.groups?.some(g => g.id === newGroup.id)
274-
? [...(prev.groups ?? []), newGroup]
275-
: prev.groups,
276-
homeworks: newHomework?.id !== undefined && !prev.homeworks?.some(h => h.id === newHomework.id)
277-
? [...(prev.homeworks ?? []), newHomework]
278-
: prev.homeworks,
279-
}) : prev);
280-
281-
if (!hasChanges) return;
282-
283-
await ApiSingleton.coursesApi.coursesEditMentorWorkspace(
284-
courseId,
285-
props.mentorId,
286-
{
287-
homeworkIds: updatedHomeworks.map(h => h.id).filter((id): id is number => id !== undefined),
288-
studentIds: selectedCourseView.selectedStudents.map(s => s.userId).filter((id): id is string => id !== undefined),
289-
groupIds: updatedGroups.map(g => g.id).filter((id): id is number => id !== undefined),
290-
}
291-
);
292-
293-
setMentorWorkspace(prev => prev ? ({
294-
...prev,
295-
homeworks: updatedHomeworks,
296-
students: selectedCourseView.selectedStudents,
297-
groups: updatedGroups
298-
}) : prev);
299-
}
300-
301233
const getDeleteMessage = (homeworkName: string, filesInfo: IFileInfo[]) => {
302234
let message = `Вы точно хотите удалить задание "${homeworkName}"?`;
303235
if (filesInfo.length > 0) {
@@ -341,10 +273,6 @@ const CourseHomeworkEditor: FC<{
341273
? await ApiSingleton.homeworksApi.homeworksAddHomework(courseId!, update)
342274
: await ApiSingleton.homeworksApi.homeworksUpdateHomework(+homeworkId!, update)
343275

344-
if (isNewHomework && updatedHomework.value) {
345-
await updateMentorFilter({newHomework: updatedHomework.value});
346-
}
347-
348276
const updatedHomeworkId = updatedHomework.value!.id!
349277
await handleFilesChange(
350278
courseId, CourseUnitType.Homework, updatedHomeworkId,
@@ -516,8 +444,7 @@ const CourseHomeworkEditor: FC<{
516444
selectedGroupId={selectedGroupId}
517445
choiceDisabled={!isNewHomework}
518446
onGroupsUpdate={props.onGroupsUpdate}
519-
onCreateNewGroup={(newGroup: GroupViewModel) => updateMentorFilter({newGroup})}
520-
groups={mentorWorkspace?.groups ?? props.groups}
447+
groups={props.groups}
521448
/>
522449
</CardContent>
523450
{!isNewHomework && !isPublished &&

0 commit comments

Comments
 (0)