Skip to content

Commit d122b2a

Browse files
release: v0.48.0 (#268)
* feat: Show grades to students (#266) * feat: Add go back button to the no rubric chosen component * refactor: Lazily import components to grade an student in a laboratory * chore: Update rubric objectives skeleton * feat(ui): Create loading state for the view to show students' grades * refactor: Add is interactive prop to highlight-able rubric component New prop to disable / enable the on-click event in the criteria cards * feat: Create view to show students their grade * perf: Lazily import grading layouts instead of grading components * refactor: Conditionally add labels to highlight-able rubric criteria The aria label property is removed when the rubric is used to show students their grade. * test: Add test to ensure students can see their grades * feat(ui): Create no rubric chosen component to show to students Show a custom component to students when teachers hasn't chosen a rubric for a laboratory. * feat(ui): Landing page (#267) * chore: Handle white-spaces on languages templates names * feat(ui): Hero section * feat(ui): Add features section to home page * chore: Remove repositories links from footer Since there are many repositories, organization profile is enough * feat(ui): Add open-source section
1 parent f114d71 commit d122b2a

File tree

52 files changed

+911
-153
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

52 files changed

+911
-153
lines changed

CHANGELOG.md

Lines changed: 10 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,45 +1,45 @@
1-
# [0.46.0](https://github.com/upb-code-labs/react-client/compare/v0.45.0...v0.46.0) (2024-01-20)
1+
# [0.48.0](https://github.com/upb-code-labs/react-client/compare/v0.47.0...v0.48.0) (2024-01-21)
22

33

44
### Features
55

6-
* Grade student ([#263](https://github.com/upb-code-labs/react-client/issues/263)) ([bba5534](https://github.com/upb-code-labs/react-client/commit/bba553440c9c24dbf1236019f124952efae58185))
6+
* **ui:** Landing page ([#267](https://github.com/upb-code-labs/react-client/issues/267)) ([254b541](https://github.com/upb-code-labs/react-client/commit/254b541ab5cd2675f03c5510604f6fd4bf5461d0))
77

88

99

10-
# [0.45.0](https://github.com/upb-code-labs/react-client/compare/v0.44.0...v0.45.0) (2024-01-19)
10+
# [0.47.0](https://github.com/upb-code-labs/react-client/compare/v0.46.0...v0.47.0) (2024-01-21)
1111

1212

1313
### Features
1414

15-
* List students' grades ([#262](https://github.com/upb-code-labs/react-client/issues/262)) ([508a9c2](https://github.com/upb-code-labs/react-client/commit/508a9c2d263d21a6db458c0092aa048f6107b44c))
15+
* Show grades to students ([#266](https://github.com/upb-code-labs/react-client/issues/266)) ([3923fd5](https://github.com/upb-code-labs/react-client/commit/3923fd5fea8fa4e73022e6fbe701eca8a0d87ead))
1616

1717

1818

19-
# [0.44.0](https://github.com/upb-code-labs/react-client/compare/v0.43.0...v0.44.0) (2024-01-17)
19+
# [0.46.0](https://github.com/upb-code-labs/react-client/compare/v0.45.0...v0.46.0) (2024-01-20)
2020

2121

2222
### Features
2323

24-
* Swap the index of two blocks ([#256](https://github.com/upb-code-labs/react-client/issues/256)) ([842114e](https://github.com/upb-code-labs/react-client/commit/842114e4017978869c3a1a4b77e190332436f440))
24+
* Grade student ([#263](https://github.com/upb-code-labs/react-client/issues/263)) ([bba5534](https://github.com/upb-code-labs/react-client/commit/bba553440c9c24dbf1236019f124952efae58185))
2525

2626

2727

28-
# [0.43.0](https://github.com/upb-code-labs/react-client/compare/v0.42.0...v0.43.0) (2024-01-17)
28+
# [0.45.0](https://github.com/upb-code-labs/react-client/compare/v0.44.0...v0.45.0) (2024-01-19)
2929

3030

3131
### Features
3232

33-
* Update password ([#255](https://github.com/upb-code-labs/react-client/issues/255)) ([ad92b51](https://github.com/upb-code-labs/react-client/commit/ad92b515fc1d91cbd085bf6cc475b0d64e0b7900))
33+
* List students' grades ([#262](https://github.com/upb-code-labs/react-client/issues/262)) ([508a9c2](https://github.com/upb-code-labs/react-client/commit/508a9c2d263d21a6db458c0092aa048f6107b44c))
3434

3535

3636

37-
# [0.42.0](https://github.com/upb-code-labs/react-client/compare/v0.41.0...v0.42.0) (2024-01-17)
37+
# [0.44.0](https://github.com/upb-code-labs/react-client/compare/v0.43.0...v0.44.0) (2024-01-17)
3838

3939

4040
### Features
4141

42-
* Update profile ([#254](https://github.com/upb-code-labs/react-client/issues/254)) ([1954d1d](https://github.com/upb-code-labs/react-client/commit/1954d1dfcd7f62d830829fa645bf3427734a3411))
42+
* Swap the index of two blocks ([#256](https://github.com/upb-code-labs/react-client/issues/256)) ([842114e](https://github.com/upb-code-labs/react-client/commit/842114e4017978869c3a1a4b77e190332436f440))
4343

4444

4545

e2e/Footer.spec.ts

Lines changed: 0 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -17,13 +17,4 @@ test("Footer should contain the correct links", async ({ page }) => {
1717
await expect(
1818
page.getByRole("link", { name: "Organization profile", exact: true })
1919
).toBeVisible();
20-
await expect(
21-
page.getByRole("link", { name: "Frontend repository", exact: true })
22-
).toBeVisible();
23-
await expect(
24-
page.getByRole("link", { name: "Main API repository", exact: true })
25-
).toBeVisible();
26-
await expect(
27-
page.getByRole("link", { name: "Tests runner repository", exact: true })
28-
).toBeVisible();
2920
});

e2e/grades/grades-workflow.spec.ts

Lines changed: 54 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,8 @@ test.describe.serial("Grades workflow", () => {
2020
const laboratoryName = "Test laboratory";
2121
const testBlockName = "Test block name";
2222

23+
const gradeComment = "This is a comment left by the teacher";
24+
2325
const studentFullName = getRandomName();
2426
const studentEmail = getRandomEmail();
2527

@@ -215,6 +217,10 @@ test.describe.serial("Grades workflow", () => {
215217
});
216218

217219
test("Student submits a solution", async ({ page }) => {
220+
// update the timeout
221+
const ONE_MINUTE_IN_MS = 60000;
222+
page.setDefaultTimeout(ONE_MINUTE_IN_MS);
223+
218224
// Login as a student
219225
await page.goto("/login");
220226
await page.getByLabel("Email").fill(studentEmail);
@@ -248,10 +254,6 @@ test.describe.serial("Grades workflow", () => {
248254
await expect(submitButton).toBeVisible();
249255
await submitButton.click();
250256

251-
// update the timeout
252-
const ONE_MINUTE_IN_MS = 60000;
253-
page.setDefaultTimeout(ONE_MINUTE_IN_MS);
254-
255257
// Assert the status phases are shown
256258
// Pending phase
257259
const pendingPhaseElm = page.getByTestId("pending-phase");
@@ -412,7 +414,7 @@ test.describe.serial("Grades workflow", () => {
412414
// ## Add a comment
413415
const commentInput = page.getByLabel("Comment");
414416
await expect(commentInput).toBeVisible();
415-
await commentInput.fill("This is a comment left by the teacher");
417+
await commentInput.fill(gradeComment);
416418

417419
const updateCommentButton = page.getByRole("button", {
418420
name: "Update comment",
@@ -493,4 +495,51 @@ test.describe.serial("Grades workflow", () => {
493495
page.getByText("The submission archive has been downloaded successfully")
494496
).toBeVisible();
495497
});
498+
499+
test("Student can see the grade", async ({ page }) => {
500+
// Login as a student
501+
await page.goto("/login");
502+
await page.getByLabel("Email").fill(studentEmail);
503+
await page.getByLabel("Password").fill(getDefaultPassword());
504+
await page.getByRole("button", { name: "Submit" }).click();
505+
506+
// Go to the course page
507+
await page.getByRole("link", { name: courseName }).click();
508+
509+
// Go to the grade page
510+
await page
511+
.getByRole("link", {
512+
name: `See grade obtained in ${laboratoryName} laboratory`
513+
})
514+
.click();
515+
516+
// Assert the criteria is highlighted
517+
const highlightedCriteria = page.getByTestId("Criteria 1 of objective 1");
518+
await expect(highlightedCriteria).toBeVisible();
519+
await expect(highlightedCriteria).toHaveAttribute(
520+
"data-is-highlighted",
521+
"true"
522+
);
523+
524+
const highlightedCriteriaWeightElm = page.getByLabel(
525+
"Criteria 1 of objective 1 weight",
526+
{ exact: true }
527+
);
528+
await expect(highlightedCriteriaWeightElm).toBeVisible();
529+
530+
const highlightedCriteriaWeight =
531+
await highlightedCriteriaWeightElm.getAttribute("value");
532+
expect(highlightedCriteriaWeight).not.toBeNull();
533+
534+
// Assert the grade and comment are shown
535+
const studentGradeInput = page.getByLabel("Grade", { exact: true });
536+
await expect(studentGradeInput).toBeVisible();
537+
await expect(studentGradeInput).toHaveValue(highlightedCriteriaWeight!);
538+
539+
const commentInput = page.getByLabel("Comment", { exact: true });
540+
await expect(commentInput).toBeVisible();
541+
await expect(commentInput).toHaveValue(
542+
"This is a comment left by the teacher"
543+
);
544+
});
496545
});

index.html

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@
1414
sizes="16x16"
1515
href="/icons/favicon-16x16.png"
1616
/>
17+
<link rel="preload" href="/images/hero-education-image.svg" as="image" />
1718
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
1819
<meta
1920
name="description"

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
{
22
"name": "react-client",
33
"private": true,
4-
"version": "0.46.0",
4+
"version": "0.48.0",
55
"type": "module",
66
"scripts": {
77
"dev": "vite",
Lines changed: 1 addition & 0 deletions
Loading

public/images/programmers-image.svg

Lines changed: 1 addition & 0 deletions
Loading
18.6 KB
Binary file not shown.
25.7 KB
Binary file not shown.
Binary file not shown.
27.2 KB
Binary file not shown.
33.9 KB
Binary file not shown.
22.7 KB
Binary file not shown.

src/components/Footer/Footer.tsx

Lines changed: 0 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -15,18 +15,6 @@ const source = [
1515
{
1616
name: "Organization profile",
1717
url: "https://github.com/upb-code-labs"
18-
},
19-
{
20-
name: "Frontend repository",
21-
url: "https://github.com/UPB-Code-Labs/react-client"
22-
},
23-
{
24-
name: "Main API repository",
25-
url: "https://github.com/UPB-Code-Labs/main-api"
26-
},
27-
{
28-
name: "Tests runner repository",
29-
url: "https://github.com/UPB-Code-Labs/tests-microservice"
3018
}
3119
];
3220

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
import { RubricObjectivesSkeleton } from "@/screens/edit-rubric/skeletons/RubricObjectivesSkeleton";
2+
3+
export const HighlightableRubricSkeleton = () => {
4+
return (
5+
<div className="flex max-w-[calc(100vw-2rem)] flex-col gap-4 md:col-span-3">
6+
{/* rubric skeleton */}
7+
<RubricObjectivesSkeleton />
8+
</div>
9+
);
10+
};

src/screens/edit-student-grade/components/grading-rubric/GradingRubric.tsx renamed to src/components/hightlightable-rubric/HighlightableRubric.tsx

Lines changed: 9 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1,31 +1,26 @@
11
import { Rubric } from "@/types/entities/rubric-entities";
22

3-
import { GradingRubricRow } from "./GradingRubricObjectiveRow";
3+
import { HighlightableRubricRow } from "./HighlightableRubricObjectiveRow";
44

5-
interface SelectableRubricProps {
5+
interface highlightableRubricProps {
66
selectedCriteriaByObjective: Record<string, string | null>;
77
laboratoryUUID: string;
88
studentUUID: string;
9-
isLoading: boolean;
109
rubric: Rubric;
10+
isInteractive?: boolean;
1111
}
1212

13-
export const GradingRubric = ({
13+
export const HighlightableRubric = ({
1414
selectedCriteriaByObjective,
1515
laboratoryUUID,
1616
studentUUID,
17-
isLoading,
18-
rubric
19-
}: SelectableRubricProps) => {
20-
// TODO: Use a proper loading component
21-
if (isLoading) {
22-
return <div>Loading rubric...</div>;
23-
}
24-
17+
rubric,
18+
isInteractive = true
19+
}: highlightableRubricProps) => {
2520
return (
2621
<div className="flex max-w-[calc(100vw-2rem)] flex-col gap-4">
2722
{rubric.objectives.map((objective, index) => (
28-
<GradingRubricRow
23+
<HighlightableRubricRow
2924
key={`selectable-objective-row-${objective.uuid}`}
3025
laboratoryUUID={laboratoryUUID}
3126
studentUUID={studentUUID}
@@ -34,6 +29,7 @@ export const GradingRubric = ({
3429
selectedCriteriaForObjective={
3530
selectedCriteriaByObjective[objective.uuid]
3631
}
32+
isInteractive={isInteractive}
3733
/>
3834
))}
3935
</div>
Lines changed: 19 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -11,27 +11,29 @@ import { useMutation, useQueryClient } from "@tanstack/react-query";
1111
import { useId } from "react";
1212
import { toast } from "sonner";
1313

14-
interface gradingRubricCriteriaRequiredUUID {
14+
interface highlightableRubricCriteriaRequiredUUID {
1515
laboratoryUUID: string;
1616
objectiveUUID: string;
1717
studentUUID: string;
1818
}
1919

20-
interface gradingRubricCriteriaCardProps {
20+
interface highlightableRubricCriteriaCardProps {
2121
objectiveCriteriaList: Criteria[];
22-
uuids: gradingRubricCriteriaRequiredUUID;
22+
uuids: highlightableRubricCriteriaRequiredUUID;
2323
criteriaIndex: number;
2424
objectiveIndex: number;
2525
isSelected?: boolean;
26+
isInteractive?: boolean;
2627
}
2728

28-
export const GradingRubricCriteriaCard = ({
29+
export const HighlightableRubricCriteriaCard = ({
2930
objectiveCriteriaList,
3031
uuids: { laboratoryUUID, objectiveUUID, studentUUID },
3132
criteriaIndex,
3233
objectiveIndex,
33-
isSelected = false
34-
}: gradingRubricCriteriaCardProps) => {
34+
isSelected = false,
35+
isInteractive = true
36+
}: highlightableRubricCriteriaCardProps) => {
3537
const criteria = objectiveCriteriaList[criteriaIndex];
3638

3739
const criteriaWeightId = useId();
@@ -223,10 +225,18 @@ export const GradingRubricCriteriaCard = ({
223225
return (
224226
<article
225227
className={`flex aspect-square w-full max-w-[18rem] flex-shrink-0 cursor-pointer flex-col gap-2 border p-4 shadow-md transition-colors hover:shadow-lg sm:w-72 ${isSelected && "border-2 border-purple-upb"}`}
226-
onClick={handleCriteriaCardClick}
227-
tabIndex={0}
228+
onClick={isInteractive ? handleCriteriaCardClick : undefined}
229+
tabIndex={isInteractive ? 0 : undefined}
228230
role="button"
229-
aria-label={`${isSelected ? "De-select" : "Select"} criteria ${criteriaIndex + 1} of objective ${objectiveIndex + 1}`}
231+
aria-label={
232+
isInteractive
233+
? `${isSelected ? "De-select" : "Select"} criteria ${criteriaIndex + 1} of objective ${objectiveIndex + 1}`
234+
: undefined
235+
}
236+
data-is-highlighted={isSelected}
237+
data-testid={`Criteria ${criteriaIndex + 1} of objective ${
238+
objectiveIndex + 1
239+
}`}
230240
>
231241
<h2 className="text-xl font-bold">Criteria {criteriaIndex + 1}</h2>
232242
<div className="flex flex-col gap-2">

0 commit comments

Comments
 (0)