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

Drew Reed - Plan for the Remainder of the Project Cycle (Assignment Grading/Viewing) #88

Open
20 tasks done
drewreed2005 opened this issue May 16, 2024 · 3 comments
Open
20 tasks done

Comments

@drewreed2005
Copy link
Collaborator

drewreed2005 commented May 16, 2024

Current State

As things currently are, the assignment object has the following attributes:

  • Assignment name
  • Date assignment was created
  • Date the assignment is due to be submitted
  • Content of the assignment

The frontend only currently has the capacity to:

  • Display the assignment name
  • Display the date that an assignment is due
  • Display the content of the assignment

The frontend is also unfinished in terms of design:

Screen Shot 2024-05-15 at 10 49 49 AM

There are unfinished and not completely functional measures that have been tested to accept file uploads to assignments.

The Ideal Final Product

Assignment Object and Methods

These should all be implemented as attributes of the assignment class:

  • Assignment name
  • Date assignment was created
  • Date the assignment is due to be submitted
  • Content of the assignment
  • The number of points the assignment is worth
  • The allowed submission file types
  • A list of assignment submissions (see details below)

Methods should be added/modified such that...

  • Assignment data can be fetched with the JWT cookie as context, determining if the user has submitted a given assignment and if they have been graded

Assignment Submission Object and Methods

The object exists already and is in progress, but should eventually contain:

  • The submitter
  • The file path of the upload
  • The grade (starting at -1 if not graded)
  • The time of submission
  • The number of submissions for the user

Methods that should exist (many currently exist) are...

  • Creating a new submission with a file upload implemented with it, using the student JWT token
  • Fetching all submissions sorted by the submitter (for teacher grading)
  • Using a JWT cookie to find all submissions for a given user
  • Using a JWT cookie to verify that the user is a teacher, a submission should be able to be graded (within the point limitations)

Frontend Redesign

This is the plan for the appearance of the page for students and their submissions:

  • Data Display
  • Submission functionality
  • Styling
Screen Shot 2024-05-15 at 12 19 45 PM

The teachers should be able to see student submissions based on the time and order of their submissions and to view a preview to the left (see below). They should also be able to submit a grade for submissions on this page (to be implemented where the bolded ratio numbers are listed):

  • Data Display
  • Grading functionality
  • Preview functionality (Raymond portion)
  • Styling
Screen Shot 2024-05-20 at 11 23 34 AM

Ideal Event Demonstration

After user creation (Kevin), site navigation (Ekam/Ishi), and class period creation (Drew?)...

  • Show assignment creation (AJ's focus)
  • Show assignment submission (Drew/Raymond focus, Drew pilots for Raymond to take following...)
  • Show teacher view of submission and grading (Drew/Raymond focus, Raymond pilots discussion of preview)

Then continue to teacher communication...

Timeline

Feature Deadline Details
Backend: New Methods, Attributes Tuesday, May 21 Finish methods for Assignment and AssignmentSubmission classes detailed in the issue above.
Frontend: Student Submission View Thursday, May 23 Finish styling and communication of backend data to the student frontend screen, including a pull that determines student relationship to an assignment
Frontend: Teacher Submission View Friday, May 24 Should be primarily adapted from the student view, but with accommodation of teacher grading capability. Raymond's preview feature will be implemented if possible, but if not, grading will at least be accommodated. Worst case, file downloads are utilized.
Backend: Testing and Update to Deployment Monday, May 27 Over this weekend, I will ensure that all changes made locally to the Assignment branch are reflected to the deployed format. Deployed link will be used on the frontend as well.
@drewreed2005
Copy link
Collaborator Author

Presentation Point

  • Bullet
  • Artifact
  • Demo
  • Check

@drewreed2005
Copy link
Collaborator Author

Progress Checkpoint: End of Monday, May 20

Code Contributions

All current progress has been on the backend in the assignment-object branch.

Reimplementing Assignment Object

The Assignment object had the points, allowed file types, and submissions attributes added and implemented in this commit. I realized I missed the allowed number of submissions attribute, so I added them in this commit.

This is the current state of the Entity:

@Data
@AllArgsConstructor
@NoArgsConstructor
@Entity
@Convert(attributeName ="assignment", converter = JsonType.class)
public class Assignment {
    // basic variable initialization goes here...
    // Constructor used when building object from an API
    public Assignment(String name, Date dateCreated, Date dateDue, String content, int points, int allowedSubmissions, String[] allowedFileTypes) {
        this.name = name;
        this.dateCreated = dateCreated;
        this.dateDue = dateDue;
        this.content = content;
        this.points = points;
        this.allowedSubmissions = allowedSubmissions;
        for (String allowedFileType : allowedFileTypes) {
            this.allowedFileTypes.add(allowedFileType);
        }
    }

Assignment Submission Object

This was all implemented quite a while ago for testing (see this commit with the starter version (non-entity, changed later) and this commit with working version). Now, it looks like the following:

@Data
@AllArgsConstructor
@NoArgsConstructor
@Entity
@Convert(attributeName ="assignmentSubmission", converter = JsonType.class)
public class AssignmentSubmission {
    // automatic unique identifier for Person record
    @Id
    @GeneratedValue(strategy = GenerationType.AUTO)
    private Long id;

    @ManyToOne(fetch = FetchType.EAGER)
    private Person submitter;

    @NonNull
    private String filePath;

    @Temporal(TemporalType.TIMESTAMP)
    private Date timeSubmitted;

    private int submissionNumber;

    private int score;

    public AssignmentSubmission(Person submitter, String filePath, Date timeSubmitted, int submissionNumber) {
        this.submitter = submitter;
        this.filePath = filePath;
        this.timeSubmitted = timeSubmitted;
        this.submissionNumber = submissionNumber;
        this.score = -1; // score is always initialized to -1 until graded
    }
}

Prior to commits, its full functionality was confirmed.

New Backend Methods

All methods are in the AssignmentAPIController file.

In the most recent commits, this method was changed to fetch all previous submissions to an assignment by the user for frontend functionality. This is what is called when a student accesses assignment data on the frontend.

    @GetMapping("/cookie/{id}")
    public ResponseEntity<?> getAssignmentWithCookie(@CookieValue("jwt") String jwtToken,
                                                              @PathVariable long id) {
        // cookie verification; person assigned to existingPerson variable...
        Assignment assignment = repository.findById(id);
        if (assignment == null) {  // bad ID
            return new ResponseEntity<>(HttpStatus.BAD_REQUEST);  // OK HTTP response: status code, headers, and body
        }
        HashMap<String, Object> assignmentData = new HashMap<>();
        assignmentData.put("role", null);
        // good ID, so continue to check relationship
        for (ClassPeriod cp : classService.getClassPeriodsByAssignment(assignment)) {
            for (Person student : cp.getStudents()) {
                if (student.getEmail().equals(existingPerson.getEmail())) {
                    assignmentData.put("role", "student"); // person has teacher access to the assignment
                }
            }
            for (Person leader : cp.getLeaders()) {
                if (leader.getEmail().equals(existingPerson.getEmail())) {
                    assignmentData.put("role", "teacher"); // person has teacher access to the assignment
                }
            }
        }
        // handler for invalid user accessing data
        if (assignmentData.get("role") == null) {
            return new ResponseEntity<>(HttpStatus.BAD_REQUEST);
        }
        // if the student is determined to have no relationship to the assignment, null indicates they cannot access w/ role
        assignmentData.put("data", assignment);
        // NOW MAKE IT ALSO FETCH PREVIOUS SUBMISSION
        ArrayList<AssignmentSubmission> personSubmissions = new ArrayList<>();
        for (AssignmentSubmission submission : assignment.getSubmissions()) {
            if (submission.getSubmitter().getEmail().equals(existingPerson.getEmail())) { // verifying user identity with email
                personSubmissions.add(submission);
            }
        }
        assignmentData.put("submissions", personSubmissions.toArray());
        return new ResponseEntity<>(assignmentData, HttpStatus.OK);    
    }

Here's a tester call made from the frontend that shows all of the data grabbed by a user:

Screen Shot 2024-05-21 at 11 14 54 AM

Here is a method that was created in this commit for fetching from the teacher page:

    @GetMapping("/cookie/{id}/grading")
    public ResponseEntity<?> getAssignmentSubmissionsWithCookie(@CookieValue("jwt") String jwtToken,
                                                                @PathVariable long id) {
        // reading cookie data to identify existingPerson in said variable...
        boolean isTeacher = false;
        // good ID, so continue to check relationship
        for (ClassPeriod cp : classService.getClassPeriodsByAssignment(assignment)) {
            for (Person leader : cp.getLeaders()) {
                if (leader.getEmail().equals(existingPerson.getEmail())) {
                    isTeacher = true; // person has teacher access to the assignment
                }
            }
        }
        // handler for invalid user accessing data
        if (!(isTeacher)) {
            return new ResponseEntity<>(HttpStatus.BAD_REQUEST);
        }
        // sending all submissions from a given assignment
        return new ResponseEntity<>(assignment.getSubmissions(), HttpStatus.OK);    
    }

Remaining Work

I realized earlier that I did not make a method for easy teacher grading that utilizes the JWT. I will finish this today before beginning work with the frontend wireframe.

@drewreed2005
Copy link
Collaborator Author

Frontend Pull Request

Click here to access.

Backend Pull Request

Click here

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant