Skip to content

Commit

Permalink
release: v0.48.0 (#268)
Browse files Browse the repository at this point in the history
* 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
  • Loading branch information
PedroChaparro authored Jan 21, 2024
1 parent f114d71 commit d122b2a
Show file tree
Hide file tree
Showing 52 changed files with 911 additions and 153 deletions.
20 changes: 10 additions & 10 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,45 +1,45 @@
# [0.46.0](https://github.com/upb-code-labs/react-client/compare/v0.45.0...v0.46.0) (2024-01-20)
# [0.48.0](https://github.com/upb-code-labs/react-client/compare/v0.47.0...v0.48.0) (2024-01-21)


### Features

* Grade student ([#263](https://github.com/upb-code-labs/react-client/issues/263)) ([bba5534](https://github.com/upb-code-labs/react-client/commit/bba553440c9c24dbf1236019f124952efae58185))
* **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))



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


### Features

* 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))
* 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))



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


### Features

* 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))
* Grade student ([#263](https://github.com/upb-code-labs/react-client/issues/263)) ([bba5534](https://github.com/upb-code-labs/react-client/commit/bba553440c9c24dbf1236019f124952efae58185))



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


### Features

* Update password ([#255](https://github.com/upb-code-labs/react-client/issues/255)) ([ad92b51](https://github.com/upb-code-labs/react-client/commit/ad92b515fc1d91cbd085bf6cc475b0d64e0b7900))
* 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))



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


### Features

* Update profile ([#254](https://github.com/upb-code-labs/react-client/issues/254)) ([1954d1d](https://github.com/upb-code-labs/react-client/commit/1954d1dfcd7f62d830829fa645bf3427734a3411))
* 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))



9 changes: 0 additions & 9 deletions e2e/Footer.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,13 +17,4 @@ test("Footer should contain the correct links", async ({ page }) => {
await expect(
page.getByRole("link", { name: "Organization profile", exact: true })
).toBeVisible();
await expect(
page.getByRole("link", { name: "Frontend repository", exact: true })
).toBeVisible();
await expect(
page.getByRole("link", { name: "Main API repository", exact: true })
).toBeVisible();
await expect(
page.getByRole("link", { name: "Tests runner repository", exact: true })
).toBeVisible();
});
59 changes: 54 additions & 5 deletions e2e/grades/grades-workflow.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,8 @@ test.describe.serial("Grades workflow", () => {
const laboratoryName = "Test laboratory";
const testBlockName = "Test block name";

const gradeComment = "This is a comment left by the teacher";

const studentFullName = getRandomName();
const studentEmail = getRandomEmail();

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

test("Student submits a solution", async ({ page }) => {
// update the timeout
const ONE_MINUTE_IN_MS = 60000;
page.setDefaultTimeout(ONE_MINUTE_IN_MS);

// Login as a student
await page.goto("/login");
await page.getByLabel("Email").fill(studentEmail);
Expand Down Expand Up @@ -248,10 +254,6 @@ test.describe.serial("Grades workflow", () => {
await expect(submitButton).toBeVisible();
await submitButton.click();

// update the timeout
const ONE_MINUTE_IN_MS = 60000;
page.setDefaultTimeout(ONE_MINUTE_IN_MS);

// Assert the status phases are shown
// Pending phase
const pendingPhaseElm = page.getByTestId("pending-phase");
Expand Down Expand Up @@ -412,7 +414,7 @@ test.describe.serial("Grades workflow", () => {
// ## Add a comment
const commentInput = page.getByLabel("Comment");
await expect(commentInput).toBeVisible();
await commentInput.fill("This is a comment left by the teacher");
await commentInput.fill(gradeComment);

const updateCommentButton = page.getByRole("button", {
name: "Update comment",
Expand Down Expand Up @@ -493,4 +495,51 @@ test.describe.serial("Grades workflow", () => {
page.getByText("The submission archive has been downloaded successfully")
).toBeVisible();
});

test("Student can see the grade", async ({ page }) => {
// Login as a student
await page.goto("/login");
await page.getByLabel("Email").fill(studentEmail);
await page.getByLabel("Password").fill(getDefaultPassword());
await page.getByRole("button", { name: "Submit" }).click();

// Go to the course page
await page.getByRole("link", { name: courseName }).click();

// Go to the grade page
await page
.getByRole("link", {
name: `See grade obtained in ${laboratoryName} laboratory`
})
.click();

// Assert the criteria is highlighted
const highlightedCriteria = page.getByTestId("Criteria 1 of objective 1");
await expect(highlightedCriteria).toBeVisible();
await expect(highlightedCriteria).toHaveAttribute(
"data-is-highlighted",
"true"
);

const highlightedCriteriaWeightElm = page.getByLabel(
"Criteria 1 of objective 1 weight",
{ exact: true }
);
await expect(highlightedCriteriaWeightElm).toBeVisible();

const highlightedCriteriaWeight =
await highlightedCriteriaWeightElm.getAttribute("value");
expect(highlightedCriteriaWeight).not.toBeNull();

// Assert the grade and comment are shown
const studentGradeInput = page.getByLabel("Grade", { exact: true });
await expect(studentGradeInput).toBeVisible();
await expect(studentGradeInput).toHaveValue(highlightedCriteriaWeight!);

const commentInput = page.getByLabel("Comment", { exact: true });
await expect(commentInput).toBeVisible();
await expect(commentInput).toHaveValue(
"This is a comment left by the teacher"
);
});
});
1 change: 1 addition & 0 deletions index.html
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
sizes="16x16"
href="/icons/favicon-16x16.png"
/>
<link rel="preload" href="/images/hero-education-image.svg" as="image" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<meta
name="description"
Expand Down
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
{
"name": "react-client",
"private": true,
"version": "0.46.0",
"version": "0.48.0",
"type": "module",
"scripts": {
"dev": "vite",
Expand Down
1 change: 1 addition & 0 deletions public/images/hero-education-image.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
1 change: 1 addition & 0 deletions public/images/programmers-image.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added public/images/screenshots/courses-list.webp
Binary file not shown.
Binary file added public/images/screenshots/grading-view.webp
Binary file not shown.
Binary file not shown.
Binary file added public/images/screenshots/laboratory-view.webp
Binary file not shown.
Binary file added public/images/screenshots/rubric-view.webp
Binary file not shown.
Binary file added public/images/screenshots/statistics-view.webp
Binary file not shown.
12 changes: 0 additions & 12 deletions src/components/Footer/Footer.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -15,18 +15,6 @@ const source = [
{
name: "Organization profile",
url: "https://github.com/upb-code-labs"
},
{
name: "Frontend repository",
url: "https://github.com/UPB-Code-Labs/react-client"
},
{
name: "Main API repository",
url: "https://github.com/UPB-Code-Labs/main-api"
},
{
name: "Tests runner repository",
url: "https://github.com/UPB-Code-Labs/tests-microservice"
}
];

Expand Down
10 changes: 10 additions & 0 deletions src/components/Skeletons/HighlightableRubricSkeleton.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
import { RubricObjectivesSkeleton } from "@/screens/edit-rubric/skeletons/RubricObjectivesSkeleton";

export const HighlightableRubricSkeleton = () => {
return (
<div className="flex max-w-[calc(100vw-2rem)] flex-col gap-4 md:col-span-3">
{/* rubric skeleton */}
<RubricObjectivesSkeleton />
</div>
);
};
Original file line number Diff line number Diff line change
@@ -1,31 +1,26 @@
import { Rubric } from "@/types/entities/rubric-entities";

import { GradingRubricRow } from "./GradingRubricObjectiveRow";
import { HighlightableRubricRow } from "./HighlightableRubricObjectiveRow";

interface SelectableRubricProps {
interface highlightableRubricProps {
selectedCriteriaByObjective: Record<string, string | null>;
laboratoryUUID: string;
studentUUID: string;
isLoading: boolean;
rubric: Rubric;
isInteractive?: boolean;
}

export const GradingRubric = ({
export const HighlightableRubric = ({
selectedCriteriaByObjective,
laboratoryUUID,
studentUUID,
isLoading,
rubric
}: SelectableRubricProps) => {
// TODO: Use a proper loading component
if (isLoading) {
return <div>Loading rubric...</div>;
}

rubric,
isInteractive = true
}: highlightableRubricProps) => {
return (
<div className="flex max-w-[calc(100vw-2rem)] flex-col gap-4">
{rubric.objectives.map((objective, index) => (
<GradingRubricRow
<HighlightableRubricRow
key={`selectable-objective-row-${objective.uuid}`}
laboratoryUUID={laboratoryUUID}
studentUUID={studentUUID}
Expand All @@ -34,6 +29,7 @@ export const GradingRubric = ({
selectedCriteriaForObjective={
selectedCriteriaByObjective[objective.uuid]
}
isInteractive={isInteractive}
/>
))}
</div>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,27 +11,29 @@ import { useMutation, useQueryClient } from "@tanstack/react-query";
import { useId } from "react";
import { toast } from "sonner";

interface gradingRubricCriteriaRequiredUUID {
interface highlightableRubricCriteriaRequiredUUID {
laboratoryUUID: string;
objectiveUUID: string;
studentUUID: string;
}

interface gradingRubricCriteriaCardProps {
interface highlightableRubricCriteriaCardProps {
objectiveCriteriaList: Criteria[];
uuids: gradingRubricCriteriaRequiredUUID;
uuids: highlightableRubricCriteriaRequiredUUID;
criteriaIndex: number;
objectiveIndex: number;
isSelected?: boolean;
isInteractive?: boolean;
}

export const GradingRubricCriteriaCard = ({
export const HighlightableRubricCriteriaCard = ({
objectiveCriteriaList,
uuids: { laboratoryUUID, objectiveUUID, studentUUID },
criteriaIndex,
objectiveIndex,
isSelected = false
}: gradingRubricCriteriaCardProps) => {
isSelected = false,
isInteractive = true
}: highlightableRubricCriteriaCardProps) => {
const criteria = objectiveCriteriaList[criteriaIndex];

const criteriaWeightId = useId();
Expand Down Expand Up @@ -223,10 +225,18 @@ export const GradingRubricCriteriaCard = ({
return (
<article
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"}`}
onClick={handleCriteriaCardClick}
tabIndex={0}
onClick={isInteractive ? handleCriteriaCardClick : undefined}
tabIndex={isInteractive ? 0 : undefined}
role="button"
aria-label={`${isSelected ? "De-select" : "Select"} criteria ${criteriaIndex + 1} of objective ${objectiveIndex + 1}`}
aria-label={
isInteractive
? `${isSelected ? "De-select" : "Select"} criteria ${criteriaIndex + 1} of objective ${objectiveIndex + 1}`
: undefined
}
data-is-highlighted={isSelected}
data-testid={`Criteria ${criteriaIndex + 1} of objective ${
objectiveIndex + 1
}`}
>
<h2 className="text-xl font-bold">Criteria {criteriaIndex + 1}</h2>
<div className="flex flex-col gap-2">
Expand Down
Loading

0 comments on commit d122b2a

Please sign in to comment.