CSC/ECE 517 Spring 2025 - E2521. UI for View submissions/assign grades (except heatgrid)

From Expertiza_Wiki
Jump to navigation Jump to search

Introduction

Project Overview

The "Assign Grades" feature focuses on developing a user interface (UI) to allow instructors to assign and manage final grades for team submissions. It displays essential information about the team, peer review scores, and submission status in a streamlined and user-friendly format.

The page also provides interactive options such as:

  • **Show Submission** – Allows the instructor to view a team's submission details.
  • **Assign Grade & Comment** – Lets the instructor enter a numeric grade and written feedback.
  • **Navigation** – Instructors can quickly go back or proceed to other pages after saving.

The primary objective is to ensure that instructors have a clear, cohesive, and intuitive interface for finalizing grades, with minimal clutter and straightforward navigation.

Design Goals

The design goals for the "Assign Grades" page are aligned with consistency, clarity, flexibility, and intuitiveness:

  • Consistency and Clearness: The page layout should be consistent with the overall Expertiza UI guidelines (font sizes, button styles, etc.) and clearly highlight essential information like the assignment title, team name, and final grade fields.
  • Minimalism: Although the page includes review scores and submission info, we aim to present them in a well-organized manner that avoids clutter. Only essential data should appear by default, with the option to toggle or reveal more details if needed.
  • Flexibility: The page should be adaptable for various use cases—whether an assignment is a team-based or individual-based, whether there are 0 or 10 peer reviews, etc.
  • Intuitiveness: The instructor should quickly grasp how to enter and save grades. The interface for missing reviews or additional feedback should be clearly labeled and easy to navigate.

Current UI Layout

Below is a screenshot (placeholder) of the current "Assign Grades" page layout. As seen in the screenshot, the UI can be improved for clarity and ease of use.

File:AssignGrades current layout.png

Detail Description of Possible and Actual Changes

1. Streamlined Display of Peer Review Scores and Submission Details

Rationale

Instructors often need to see peer review scores before assigning a final grade. However, an overly dense table or complicated layout can be confusing. Our goal is to provide a clean table for review scores and a simple toggle for submission details.

Existing Design

In the existing design, peer review scores might appear in multiple sections, and submission data is either hidden or not clearly labeled.

Possible Changes

  • 1. Combine review scores into one table: Merge all relevant columns (reviewer, question, score) into a single table component, using consistent styling.
  • 2. Provide a "Show Submission" toggle: Let instructors expand or collapse the submission details, reducing clutter if no submission data is available.

Actual Changes

Below is a screenshot (placeholder) of the revised layout. Notice the consolidated review scores table and a single toggle button for the submission.

  • Updated Files
    • AssignGrades.tsx** – Contains the new code to fetch or display dummy data for review scores and submission details.

2. Improved Grade & Comment Entry

Rationale

In the existing UI, instructors sometimes struggle to find where to input grades or comments, or the form is not clearly validated. A more prominent grade entry section, with validation and error handling, is crucial.

Existing Design

Grade input was placed at the bottom of the page with no clear labeling or feedback.

Possible Changes

  • 1. Make the grade and comment fields more prominent: Use larger labels and consistent spacing.
  • 2. Add form validation and error handling: If the user submits an empty grade, display an alert.

Actual Changes

The form is now clearly labeled. An error message is shown if the user tries to save without entering a grade.

  • Updated Files

3. Navigation on Save

Current Limitation: Previously, instructors had to manually navigate back to the homepage or another route after saving a grade. This step could be confusing or tedious.

Proposed Solution: Add a redirect to the homepage (or a relevant dashboard) upon successful grade submission.

Implementation Details:

const handleSave = () => {
  // Validate data, save grade
  alert("Grade and comment saved successfully!");
  navigate("/");
};

Updated Files:

  • **AssignGrades.tsx** – The `handleSave` function now calls `navigate("/")` after a successful save.

4. Export Options for Grade Records

Current Limitation: While instructors can see final grades, they cannot quickly export them for offline record-keeping.

Proposed Solution: Add export buttons below the peer review scores table to download data as CSV or Excel.

Implementation Details:

const exportGradeData = (format: "csv" | "xlsx") => {
    // transform data, use SheetJS
    // XLSX.writeFile(workbook, `grades.${format}`);
};

<div style={{ marginTop: "10px" }}>
    <button onClick={() => exportGradeData("csv")}>Export to CSV</button>
    <button onClick={() => exportGradeData("xlsx")}>Export to Excel</button>
</div>

Frontend (React & TypeScript)

Files to be Potentially Modified

All files to be modified are located in the `src/pages/AssignGrades` folder (or an equivalent folder in your repository). The primary files are:

  • `src/pages/AssignGrades/AssignGrades.tsx`
  • `src/pages/AssignGrades/ReviewTable.tsx`
  • `src/pages/AssignGrades/Data/dummyData.json` (if using local JSON data)

Below is a **source code** snippet for the core "Assign Grades" page, demonstrating how we handle dummy data, display review tables, and navigate on save.

'''AssignGrades.tsx'''
import React, { useState } from "react";
import { Button, Container, Row, Col, Form } from "react-bootstrap";
import { useNavigate } from "react-router-dom";

// Dummy data
import ReviewTable from "./ReviewTable";
import dummyData from "./Data/dummyData.json";

const AssignGrades: React.FC = () => {
  const navigate = useNavigate();
  const [showSubmission, setShowSubmission] = useState(false);
  const [grade, setGrade] = useState("");
  const [comment, setComment] = useState("");

  const handleSave = () => {
    if (!grade) {
      alert("Grade is required!");
      return;
    }
    console.log("Saving Grade:", grade, "Comment:", comment);
    alert("Grade and comment saved successfully!");
    // Navigate to home page after saving
    navigate("/");
  };

  return (
    <Container fluid className="px-4">
      <Row className="mt-4">
        <Col className="text-center">
          <h2>Summary Report for assignment: Program 1</h2>
          <p>Team: ExampleTeam</p>
          <hr />
        </Col>
      </Row>

      <Row>
        <Col>
          <Button
            variant="outline-info"
            size="sm"
            onClick={() => setShowSubmission((prev) => !prev)}
          >
            {showSubmission ? "Hide Submission" : "Show Submission"}
          </Button>

          {showSubmission && (
            <div className="mt-2">
              <strong>No Submission Available</strong>
            </div>
          )}
        </Col>
      </Row>

      <Row className="mt-4">
        <Col>
          <h3>Teammate Review</h3>
          {dummyData && dummyData.length > 0 ? (
            <ReviewTable data={dummyData} />
          ) : (
            <p>There are no reviews for this assignment</p>
          )}
        </Col>
      </Row>

      <Row className="mt-4">
        <Col>
          <h3>Grade and comment for submission</h3>
          <Form.Group controlId="gradeInput" className="mb-3 mt-2" style={{ maxWidth: "200px" }}>
            <Form.Label>Grade</Form.Label>
            <Form.Control
              type="number"
              value={grade}
              onChange={(e) => setGrade(e.target.value)}
              placeholder="Enter numeric grade"
            />
          </Form.Group>

          <Form.Group controlId="commentInput" className="mb-3" style={{ maxWidth: "500px" }}>
            <Form.Label>Comments</Form.Label>
            <Form.Control
              as="textarea"
              rows={3}
              value={comment}
              onChange={(e) => setComment(e.target.value)}
              placeholder="Enter comments"
            />
          </Form.Group>

          <Button variant="primary" onClick={handleSave}>
            Save
          </Button>
          <Button variant="secondary" className="ms-2" onClick={() => navigate(-1)}>
            Back
          </Button>
        </Col>
      </Row>
    </Container>
  );
};

export default AssignGrades;

Use Case Diagram

Below is a simplified use case diagram for the "Assign Grades" page. The instructor can view submissions, enter grades, and then return to the main page.

Actors:

  • Instructor — The primary user who assigns grades and leaves comments.

Use Cases:

  • View peer reviews – Instructor sees a list of peer reviews or scores.
  • Show submission – Instructor checks the submitted work or toggles it off.
  • Assign a grade – Instructor inputs a numeric grade and optional comments.
  • Save & navigate – After saving, the instructor is redirected to the home page.

Test Plan

To validate the updated "Assign Grades" page’s functionality, usability, and performance while meeting clarity, consistency, and intuitiveness goals.

Testing Scope

1. Component Validation

  *Test the `AssignGrades.tsx` form logic.
  *Test the `ReviewTable.tsx` to ensure it renders dummy data correctly.

2. Dummy Data Rendering

  *Validate that `dummyData.json` populates the table as expected.

3. Navigation

  *Confirm that clicking “Save” redirects the user to the home page (`"/"`).
  *Confirm that “Back” navigates to the previous page.

4. Form Validation

  *Ensure an error is shown if the user attempts to save with an empty grade.

Test Cases:

Test Case ID Test Description Expected Outcome Priority Status
TC001 Verify "Show Submission" toggle Clicking the button reveals or hides the "No Submission Available" text Medium Pending
TC002 Validate grade input Submitting without a grade shows an error alert High Pending
TC003 Test successful save Saving a valid grade triggers success alert and navigates home High Pending

Testing Strategy

  • **Unit Testing**:
 * Write Jest tests for `AssignGrades.tsx` to confirm it renders, handles form state, and calls `navigate("/")` properly.
 * Validate `ReviewTable.tsx` to ensure it displays dummy data.
  • **Integration Testing**:
 * Test the interaction between the form submission and the table display to confirm consistent data handling.
  • **Accessibility Testing**:
 * Check keyboard navigation and form labels.

Test Cases

  • src/pages/Assignments/AssignGrades.test.tsx
  // src/pages/Assignments/AssignGrades.test.tsx

import React from "react";
import { render, screen, fireEvent } from "@testing-library/react";
import { BrowserRouter } from "react-router-dom";
import { Provider } from "react-redux";
import { configureStore } from "@reduxjs/toolkit";
import "@testing-library/jest-dom";
// Import your root reducer (adjust the path as needed)
import rootReducer from "../../store/rootReducer";

// Import the component under test
import AssignGrades from "./AssignGrades";

// Example: Mock window.alert so we can check if it's called
const alertMock = jest.spyOn(window, "alert").mockImplementation(() => {});

describe("AssignGrades page", () => {
  // Create a single Redux store for all tests in this file
  const store = configureStore({
    reducer: rootReducer,
    // You can optionally add a preloadedState: {...} if needed
  });

  afterAll(() => {
    alertMock.mockRestore();
  });

  // TC001: Verify "Show Submission" toggle
  test("TC001: Verify 'Show Submission' toggle", () => {
    render(
      <Provider store={store}>
        <BrowserRouter>
          <AssignGrades />
        </BrowserRouter>
      </Provider>
    );

    // Initially, "No Submission Available" should NOT be visible
    expect(screen.queryByText("No Submission Available")).not.toBeInTheDocument();

    // Click the toggle button
    const toggleButton = screen.getByText("Show Submission");
    fireEvent.click(toggleButton);

    // Now "No Submission Available" should be visible
    expect(screen.getByText("No Submission Available")).toBeInTheDocument();

    // Click again to hide
    const hideButton = screen.getByText("Hide Submission");
    fireEvent.click(hideButton);

    // It should disappear again
    expect(screen.queryByText("No Submission Available")).not.toBeInTheDocument();
  });

  // TC002: Validate grade input
  test("TC002: Validate grade input (no grade => error alert)", () => {
    render(
      <Provider store={store}>
        <BrowserRouter>
          <AssignGrades />
        </BrowserRouter>
      </Provider>
    );

    // Click 'Save' without entering a grade
    const saveButton = screen.getByText("Save");
    fireEvent.click(saveButton);

    // Check that the alert was called with "Grade is required!" (per your code)
    expect(alertMock).toHaveBeenCalledWith("Grade is required!");
  });

  // TC003: Test successful save
  test("TC003: Test successful save (valid grade => success alert & navigate)", () => {
    render(
      <Provider store={store}>
        <BrowserRouter>
          <AssignGrades />
        </BrowserRouter>
      </Provider>
    );

    // Enter a valid grade
    const gradeInput = screen.getByLabelText("Grade");
    fireEvent.change(gradeInput, { target: { value: "90" } });

    // Enter a comment (optional)
    const commentInput = screen.getByLabelText("Comments");
    fireEvent.change(commentInput, { target: { value: "Good job!" } });

    // Click Save
    const saveButton = screen.getByText("Save");
    fireEvent.click(saveButton);

    // Check alert
    expect(alertMock).toHaveBeenCalledWith("Grade and comment saved successfully!");
    // If you mock useNavigate, you can also check it was called with "/"
    // e.g. expect(mockNavigate).toHaveBeenCalledWith("/");
  });
});

Conclusion

This wiki outlines the updates to the "Assign Grades" page, focusing on a more streamlined UI, intuitive grade entry, and straightforward navigation. By consolidating peer review data into a single table, improving form validation, and adding clear navigation on save, the new design aims to reduce confusion and enhance the instructor experience. The React + TypeScript implementation ensures maintainability and scalability for future improvements.

List of Project Links

  • GitHub Repository: [2]
  • Example Pull Request: [3]

Project Mentor

Prathyusha Kodaloi (pkodali@ncsu.edu)

Team Members

  • Harsh Vora (unityid: hkvora@ncsu.edu)
  • Martina Viola (unityid: mmviola)