CSC/ECE 517 Spring 2024 - E2430 Reimplement student task view

From Expertiza_Wiki
Jump to navigation Jump to search

Expertiza Background

Expertiza is an open-source web application built on Ruby on Rails that enables instructors to create customized assignments with topic lists for students to choose from. It facilitates team formation, allowing students to collaborate on assignments and projects. Expertiza supports peer review processes where students can provide feedback on each other's submissions across various document formats, including URLs and wiki pages. This freely available platform provides a flexible and comprehensive solution for managing assignments, teamwork, and peer evaluations.

Project Description

Enhance the student task view interface in Expertiza by re-implementing the front-end using React JS and TypeScript. The primary objectives are to improve responsiveness, and usability, provide real-time updates, and enhance the overall student experience.

This project will concentrate on the following features:

  1. Task Details Display: Show all the important information about assignments like name, due date, progress, review status, and any badges.
  2. Task Interaction: Make it easy for users to submit, request revisions, and see feedback. Let them move through different parts of the task easily.
  3. Timeline: Show a visual timeline with due dates and let users easily see where they are in the task.
  4. Lazy Loading: Make the page load faster by only loading what's needed, so users have a smoother experience.

Sample Data Used

An interface called "Deadlines" was created in the "interfaces.ts" file of the repository. This interface was designed to structure information related to deadlines. The implementation can be viewed here, with the code added at the end of the file.

To obtain the next upcoming deadline, code was added in the DeadlineUtil.tsx file. Here's a simplified version of the code:

export const getNextDeadline = (): Deadline | null => {
  const now = new Date();
  // Filter the deadlines to get only the upcoming ones
  const upcomingDeadlines = deadlines.filter(deadline => new Date(deadline.date) > now);
  // Return the earliest upcoming deadline, or null if there are no upcoming deadlines
  return upcomingDeadlines.length > 0 ? upcomingDeadlines[0] : null;
};

Moreover, dummy data for the deadlines was included, which is then displayed by the "Deadlines" component within the "StudentTaskView" component. This data serves testing purposes, and it's recommended that future team members delete this file if real data can be retrieved from the database. This data is also located in the same file. Here is the dummy deadlines data provided below

export const deadlines: Deadline[] = [
    {
        id: 1,
        date: "2024-03-22",
        description: "Submit Assignment Round 1",
    },
    {
        id: 2,
        date: "2024-03-27",
        description: "Review Assignment Round 1",
    },
    {
        id: 3,
        date: "2024-04-04",
        description: "Submit Assignment Round 2",
    },
    {
        id: 4,
        date: "2024-04-07",
        description: "Review Assignment Round 2",
    },
];

Sample data has been added to the assignments table for the purpose of testing. Only essential information necessary for display has been included, resulting in a subset of the available columns being populated. Specifically, two rows of sample data have been entered. The provided sample data can be found below.

[
  {
    "id": 4,
    "name": "program5",
    "directory_path": null,
    "submitter_count": null,
    "course_id": 1,
    "instructor_id": 1,
    "private": null,
    "num_reviews": null,
    "num_review_of_reviews": null,
    "num_review_of_reviewers": null,
    "reviews_visible_to_all": null,
    "num_reviewers": null,
    "spec_location": null,
    "max_team_size": null,
    "staggered_deadline": null,
    "allow_suggestions": 15,
    "days_between_submissions": null,
    "review_assignment_strategy": null,
    "max_reviews_per_submission": null,
    "review_topic_threshold": null,
    "copy_flag": null,
    "rounds_of_reviews": null,
    "microtask": null,
    "require_quiz": null,
    "num_quiz_questions": null,
    "is_coding_assignment": null,
    "is_intelligent": null,
    "calculate_penalty": null,
    "late_policy_id": null,
    "is_penalty_calculated": null,
    "max_bids": null,
    "show_teammate_reviews": null,
    "availability_flag": null,
    "use_bookmark": null,
    "can_review_same_topic": null,
    "can_choose_topic_to_review": null,
    "is_calibrated": null,
    "is_selfreview_enabled": 1,
    "reputation_algorithm": null,
    "is_anonymous": null,
    "num_reviews_required": null,
    "num_metareviews_required": null,
    "num_metareviews_allowed": null,
    "num_reviews_allowed": null,
    "simicheck": null,
    "simicheck_threshold": null,
    "is_answer_tagging_allowed": null,
    "has_badge": null,
    "allow_selecting_additional_reviews_after_1st_round": null,
    "sample_assignment_id": null,
    "created_at": "2024-03-17 06:01:33.396814",
    "updated_at": "2024-03-17 06:01:33.396814"
  },
  {
    "id": 5,
    "name": "program6",
    "directory_path": null,
    "submitter_count": null,
    "course_id": 1,
    "instructor_id": 1,
    "private": null,
    "num_reviews": null,
    "num_review_of_reviews": null,
    "num_review_of_reviewers": null,
    "reviews_visible_to_all": null,
    "num_reviewers": null,
    "spec_location": "http://example.com/assignment_spec",
    "max_team_size": 3,
    "staggered_deadline": null,
    "allow_suggestions": 15,
    "days_between_submissions": 15,
    "review_assignment_strategy": null,
    "max_reviews_per_submission": null,
    "review_topic_threshold": null,
    "copy_flag": null,
    "rounds_of_reviews": null,
    "microtask": null,
    "require_quiz": 1,
    "num_quiz_questions": null,
    "is_coding_assignment": null,
    "is_intelligent": null,
    "calculate_penalty": null,
    "late_policy_id": null,
    "is_penalty_calculated": null,
    "max_bids": null,
    "show_teammate_reviews": null,
    "availability_flag": null,
    "use_bookmark": null,
    "can_review_same_topic": null,
    "can_choose_topic_to_review": null,
    "is_calibrated": null,
    "is_selfreview_enabled": null,
    "reputation_algorithm": null,
    "is_anonymous": null,
    "num_reviews_required": null,
    "num_metareviews_required": null,
    "num_metareviews_allowed": null,
    "num_reviews_allowed": null,
    "simicheck": null,
    "simicheck_threshold": null,
    "is_answer_tagging_allowed": null,
    "has_badge": null,
    "allow_selecting_additional_reviews_after_1st_round": null,
    "sample_assignment_id": null,
    "created_at": "2024-03-17 06:01:33.396814",
    "updated_at": "2024-03-17 06:01:33.396814"
  }
]

Files modified in current project

The App.tsx file was modified to incorporate the LazyLoadedStudentTaskViews component, housing the lazy-loaded content of the student task view component, and the StudentTasks component. Two directories named StudentTasks and StudentTaskViews were created inside the pages directory. Inside the StudentTasks folder, a dummy StudentTask.tsx file was added with placeholder code to redirect to the specific student task view.

Design Principles

In adherence to software design principles, the codebase upholds the Single Responsibility Principle (SRP), emphasizing that each component or function should serve a singular purpose to minimize the need for changes. Additionally, the concept of Separation of Concerns is applied, whereby the logic is segmented into smaller, more manageable functions to enhance maintainability. Dependency Injection is implemented, ensuring that dependencies such as assignments and authorization are passed as arguments rather than accessed directly. Notably, specific functions like checkShowWork, checkReviewAvailability, and checkReviewableTopics from the StudentTaskView file are extracted to improve readability and testability, while the renderDeadline function enhances code readability and maintainability by handling deadline rendering tasks.

Student Task Page

The StudentTask.tsx file contains a React component called `StudentTask`. This page can be viewed when `Assignments` is clicked from the header. This component generates a link to view a specific assignment. It uses the React Router DOM's `<Link>` component to create the link. Inside the link, it includes the assignment ID as a route parameter. When users click on the link, it takes them to the corresponding assignment view page. Currently, it's set up to show Assignment 5, according to the dummy data added to the assignments database, but this step should be eliminated once the ID can be fetched directly from the database.

This mock webpage was designed to display assignment details, and clicking on a specific assignment will redirect users to its corresponding task view page.

Student Task View Page

The StudentTaskView.tsx file contains a React component named `StudentTaskView`. This component is responsible for rendering the student task view, including assignment details, deadlines, and various interaction options based on user permissions. It imports necessary modules and functions from React and other custom utility files. Within the component, it fetches assignment data using the `useEffect` hook. This component can be found below.

  useEffect(() => { // Fetch assignment data on component mount
    const fetchAssignment = async () => {
      try {
        const assignmentData = await loadAssignment({ params: { id } });
        setAssignment(assignmentData);
      } catch (error) {
        console.error('Error fetching assignment:', error);
      }
    };

    fetchAssignment(); // Call fetchAssignment function

    return () => {
      // Cleanup code here
    };
  }, [id]); // Include ID in the dependency array to re-fetch assignment data when ID changes

The file also displays a loading message if data is not yet available. It then renders assignment details and buttons for submitting work or reviewing. The below component renders assignment details, interaction options, and deadlines. It uses conditional rendering to display buttons and options based on user permissions and deadlines. Deadlines are rendered using the map function to iterate over the list of deadlines and render each one using the renderDeadline function. Each deadline displayed in the scrollbar turns red once it has passed, enhancing assignment tracking and progress monitoring. The "Your Work" link remains active only when the next deadline is for submitting the assignment; otherwise, it becomes inactive for reviewing assignments.

  function renderDeadline(deadline: any, index: number) { // Render each deadline
    return (
      <li key={deadline.id} style={styles.li} className={isDeadlinePassed(deadline) ? 'li complete' : 'li'}>
        <div style={styles.timestamp} className="timestamp">
          <p>{deadline.date}</p>
        </div>
        <div style={styles.status} className="status">
          <p style={styles.statusP}>
            {deadline.id && checkShowLink(index, deadlines) ? ( // Conditionally render link based on deadline status
              <a href={`controller: 'response', action: 'view', id: ${deadline.id}`} target="_blank">
                {deadline.description}
              </a>
            ) : (
              deadline.description
            )}
          </p>
          <div style={isDeadlinePassed(deadline) ? { ...styles.statusBefore, ...styles.completeStatusBefore } : styles.statusBefore}></div>
        </div>
      </li>
    );
  }
};


On the other hand, the LazyStudentTaskView.tsx file introduces the React functional component named `LazyLoadedStudentTaskView`. This component is designed to implement lazy loading functionality for the student task view component, allowing for deferred loading of content until it's required, thus enhancing the performance of the application.

The StudentTaskViewStyle.ts file contains the styling definitions for the `StudentTaskView` component. It defines CSS styles using an object notation for various elements such as the timeline, list items, timestamps, and status indicators. These styles are applied to elements within the `StudentTaskView` component to ensure a consistent and visually appealing presentation of assignment details and deadlines.

The following depicts the current student task view page for a specific assignment in Expertiza, followed by the student task view page presented for the reimplementation project.


Expertiza Student Task View:


Current implementation of Student Task view:

Lazy Loading

Implementing Lazy Loading for Enhanced Performance

In order to enhance website responsiveness and optimize performance, a strategic approach involves the utilization of lazy loading for components. This technique defers the loading of specific components until they are actually required by the client, thereby reducing initial load times and conserving network bandwidth.

Background

React applications, by default, bundle all JavaScript files, leading to larger initial payloads sent to the client. As the application scales, this can result in prolonged load times and unnecessary data transfer for components that may not be immediately needed. Lazy loading addresses this challenge by postponing the loading of components until they are essential for rendering. For more information on code splitting and lazy loading in React, refer to the official documentation: https://legacy.reactjs.org/docs/code-splitting.html

Implementation

Lazy loading in React can be implemented using the lazy function along with Suspense to asynchronously load components. This approach ensures that components are fetched from the server only when they are first rendered, thereby enhancing performance and minimizing the initial load size.

This component is responsible for lazy loading the `StudentTaskView` component to improve performance.

const LazyStudentTaskView = React.lazy(() => import('./StudentTaskView'));

It uses the React `Suspense` component to render a fallback UI while the `StudentTaskView` component is being loaded asynchronously. Inside the component, it fetches assignment data similarly to `StudentTaskView.tsx`, and renders the `LazyStudentTaskView` component within the `Suspense` component.

    <Suspense fallback={<div>Loading Student Task View...</div>}>
      <LazyStudentTaskView />
    </Suspense>

The LazyStudentTaskView component is dynamically imported using the React.lazy function, which asynchronously loads the component when it is first rendered. Within the Suspense component, a fallback UI is provided to display a loading message while the component is being loaded asynchronously.

Lazy loading of components provides a powerful strategy to enhance website responsiveness and optimize overall performance by deferring the loading of non-essential components until they are required. By adopting lazy loading, React applications can achieve expedited initial load times and streamline network bandwidth utilization.

Scope for future improvement

Database Integration

In the current implementation, test data was utilized to populate the tables. However, accessing data from the SQL server hosted on the backend via API endpoints is necessary. This integration would enable dynamic retrieval of data, ensuring that the application reflects the most up-to-date information. Additionally, there might be a need to modify existing tables by adding or removing columns to align with any updates or changes in the table structure.

Search and Filter Functionality

Implementing search and filter functionality enables users to swiftly locate specific tables or records within the database. Intuitive features like keyword search, criteria-based filtering, and instant suggestions optimize user experience, while persistent filters and clear error handling ensure seamless navigation and efficient retrieval of relevant information.

Peer Review Information

For those who wish to access the Expertiza application linked to this assignment, the login details are provided below:

Admin credentials: Username -> admin, Password -> password123

The expertiza application can be accessed by running the front end and back end simultaneously on your local laptop. The instructions on how to run the application is on the respective repositories.

Github repository

Here are the links to the front-end and back-end reimplementations:

Front end:
https://github.com/Shravsssss/reimplementation-front-end

These repositories are connected to the GitHub Project, which contains the necessary issues for project implementation.
https://github.com/users/Shravsssss/projects/1

These changes can be viewed in this Pull Request.

Team

Mentor:

Kashika Malick (kmalick@ncsu.edu)

Students:

Sravya Yepuri (syepuri@ncsu.edu)

Hasini Chenchala (hchench@ncsu.edu)

Chirag Hegde (chegde@ncsu.edu)