- )
+ )
} else {
return(
diff --git a/FrontEndReact/src/View/Student/View/AssessmentTask/ViewAssessmentTaskInstructions.js b/FrontEndReact/src/View/Student/View/AssessmentTask/ViewAssessmentTaskInstructions.js
index 92c622280..97324edf6 100644
--- a/FrontEndReact/src/View/Student/View/AssessmentTask/ViewAssessmentTaskInstructions.js
+++ b/FrontEndReact/src/View/Student/View/AssessmentTask/ViewAssessmentTaskInstructions.js
@@ -2,188 +2,194 @@ import React, { Component } from "react";
import 'bootstrap/dist/css/bootstrap.css';
import Button from '@mui/material/Button';
import {genericResourcePOST} from '../../../../utility.js';
-import Cookies from 'universal-cookie';
-
-
+import Cookies from 'universal-cookie';
class ViewAssessmentTaskInstructions extends Component {
- constructor(props) {
- super(props);
+ constructor(props) {
+ super(props);
- this.state = {
- categories: this.props.rubrics["category_json"],
- instructions: this.props.navbar.state.chosenAssessmentTask["comment"],
- }
- }
-
- handleContinueClick = async () => {
- const navbar = this.props.navbar;
- const state = navbar.state;
- const cookies = new Cookies();
-
- try {
- const userId = cookies.get('user')?.user_id;
- if (!userId) {
- console.error('User ID not found in cookies');
- this.props.navbar.setNewTab("ViewStudentCompleteAssessmentTask");
- return;
+ this.state = {
+ categories: this.props.rubrics["category_json"],
+ instructions: this.props.navbar.state.chosenAssessmentTask["comment"],
+ skipInstructions: this.props.navbar.state.skipInstructions,
}
+ }
- const completedAssessmentId = state.chosenCompleteAssessmentTask?.completed_assessment_id;
- if (!completedAssessmentId) {
- console.error('Completed assessment ID not found');
- this.props.navbar.setNewTab("ViewStudentCompleteAssessmentTask");
- return;
+ handleContinueClick = async () => {
+ const navbar = this.props.navbar;
+ const state = navbar.state;
+ const cookies = new Cookies();
+
+ try {
+ const userId = cookies.get('user')?.user_id;
+ if (!userId) {
+ console.error('User ID not found in cookies');
+ this.props.navbar.setNewTab("ViewStudentCompleteAssessmentTask");
+ return;
+ }
+
+ const completedAssessmentId = state.chosenCompleteAssessmentTask?.completed_assessment_id;
+ if (!completedAssessmentId) {
+ console.error('Completed assessment ID not found');
+ this.props.navbar.setNewTab("ViewStudentCompleteAssessmentTask");
+ return;
+ }
+
+ await genericResourcePOST(
+ '/feedback',
+ this,
+ JSON.stringify({
+ user_id: userId,
+ completed_assessment_id: completedAssessmentId
+ })
+ );
+
+ } catch (error) {
+ console.error('Error recording feedback view:', error);
}
- await genericResourcePOST(
- '/feedback',
- this,
- JSON.stringify({
- user_id: userId,
- completed_assessment_id: completedAssessmentId
- })
- );
-
- } catch (error) {
- console.error('Error recording feedback view:', error);
+ this.props.navbar.setNewTab("ViewStudentCompleteAssessmentTask");
}
- this.props.navbar.setNewTab("ViewStudentCompleteAssessmentTask");
-}
+ render() {
+ const skipInstructions = this.state.skipInstructions;
- render() {
- var assessmentTaskName = this.props.navbar.state.chosenAssessmentTask.assessmentTaskName;
-
- var rubricName = this.props.rubrics["rubric_name"];
-
- var rubricDescription = this.props.rubrics["rubric_description"];
-
- var categoryList = Object.keys(this.state.categories).map((category, index) => {
-
- if(index !== Object.keys(this.state.categories).length-1) {
- category += ", ";
- }
-
- return category;
- });
-
- return (
- <>
-
+ >
+ )
+ }
}
export default ViewAssessmentTaskInstructions;
diff --git a/FrontEndReact/src/View/Student/View/AssessmentTask/ViewAssessmentTasks.js b/FrontEndReact/src/View/Student/View/AssessmentTask/ViewAssessmentTasks.js
index 364fc3c12..21e4cd142 100644
--- a/FrontEndReact/src/View/Student/View/AssessmentTask/ViewAssessmentTasks.js
+++ b/FrontEndReact/src/View/Student/View/AssessmentTask/ViewAssessmentTasks.js
@@ -10,7 +10,6 @@ class ViewAssessmentTasks extends Component {
constructor(props) {
super(props);
-
this.isObjectFound = (atId) => {
var completedAssessments = this.props.completedAssessments;
@@ -36,7 +35,7 @@ class ViewAssessmentTasks extends Component {
if (assessmentTasks["number_of_teams"] !== null) // If the number of teams is specified, use that
{
count = assessmentTasks["number_of_teams"]
- } else { // Otherwise, use the number of fixed teams
+ } else { // Otherwise, use the number of fixed teams
count = this.props.counts[1];
}
} else {
@@ -72,7 +71,9 @@ class ViewAssessmentTasks extends Component {
if (role["role_id"] === 5) {
chosenCAT = this.props.completedAssessments;
}
+
var assessmentTasks = this.props.assessmentTasks;
+ // var completedAssessmentTasks = this.props.completedAssessments;
const columns = [
{
@@ -84,6 +85,22 @@ class ViewAssessmentTasks extends Component {
setCellProps: () => { return { width:"300px"} },
}
},
+ {
+ name: "unit_of_assessment",
+ label: "Unit of Assessment",
+ options: {
+ filter: true,
+ setCellHeaderProps: () => { return { width:"270px"}},
+ setCellProps: () => { return { width:"270px"} },
+ customBodyRender: (isTeam) => {
+ return (
+
+ {isTeam ? "Team" : "Individual"}
+
+ )
+ }
+ },
+ },
{
name: "due_date",
label: "Due Date",
@@ -127,6 +144,10 @@ class ViewAssessmentTasks extends Component {
setCellHeaderProps: () => { return { align:"center", width:"140px", className:"button-column-alignment"}},
setCellProps: () => { return { align:"center", width:"140px", className:"button-column-alignment"} },
customBodyRender: (atId) => {
+ // let at = assessmentTasks.find((at) => at["assessment_task_id"] === atId);
+ // let filledByStudent = at.completed_by_role_id === 5;
+ let filledByStudent = true;
+
return (
)
-
}
}
}
diff --git a/FrontEndReact/src/View/Student/View/CompletedAssessmentTask/StudentCompletedAssessmentTasks.js b/FrontEndReact/src/View/Student/View/CompletedAssessmentTask/StudentCompletedAssessmentTasks.js
index e9bed4e28..e8a5a7913 100644
--- a/FrontEndReact/src/View/Student/View/CompletedAssessmentTask/StudentCompletedAssessmentTasks.js
+++ b/FrontEndReact/src/View/Student/View/CompletedAssessmentTask/StudentCompletedAssessmentTasks.js
@@ -54,6 +54,9 @@ class StudentCompletedAssessmentTasks extends Component {
completedAssessments,
} = this.state;
+ // const filteredATs = this.props.filteredAssessments; // Currently unused, but may be in the future.
+ const filteredCATs = this.props.filteredCompleteAssessments;
+
if (errorMessage) {
return(
@@ -74,7 +77,7 @@ class StudentCompletedAssessmentTasks extends Component {
@@ -83,4 +86,4 @@ class StudentCompletedAssessmentTasks extends Component {
}
}
-export default StudentCompletedAssessmentTasks;
\ No newline at end of file
+export default StudentCompletedAssessmentTasks;
diff --git a/FrontEndReact/src/View/Student/View/CompletedAssessmentTask/ViewCompletedAssessmentTasks.js b/FrontEndReact/src/View/Student/View/CompletedAssessmentTask/ViewCompletedAssessmentTasks.js
index fbce13e9b..82e3bb496 100644
--- a/FrontEndReact/src/View/Student/View/CompletedAssessmentTask/ViewCompletedAssessmentTasks.js
+++ b/FrontEndReact/src/View/Student/View/CompletedAssessmentTask/ViewCompletedAssessmentTasks.js
@@ -8,96 +8,101 @@ import { genericResourcePOST, getHumanReadableDueDate } from "../../../../utilit
class ViewCompletedAssessmentTasks extends Component {
- render() {
- var navbar = this.props.navbar;
+ render() {
+ // var navbar = this.props.navbar;
- var completedAssessments = this.props.completedAssessments;
- var assessmentTasks = this.props.assessmentTasks;
+ var completedAssessments = this.props.completedAssessments;
+ var assessmentTasks = this.props.assessmentTasks;
- const columns = [
- {
- name: "assessment_task_name",
- label: "Task Name",
- options: {
- filter: true,
- setCellHeaderProps: () => { return { width:"250px" } },
- setCellProps: () => { return { width:"250px" } },
- }
- },
- {
- name: "initial_time",
- label: "Initial Time",
- options: {
- filter: true,
- setCellHeaderProps: () => { return { width:"150px" } },
- setCellProps: () => { return { width:"150px" } },
- customBodyRender: (initial_time) => {
- return(
- <>
- {initial_time ? getHumanReadableDueDate(initial_time) : "N/A"}
- >
- );
- }
- }
- },
- {
- name: "last_update",
- label: "Last Update",
- options: {
- filter: true,
- setCellHeaderProps: () => { return { width:"150px" } },
- setCellProps: () => { return { width:"150px" } },
- customBodyRender: (last_update) => {
- return(
- <>
- {last_update ? getHumanReadableDueDate(last_update) : "N/A"}
- >
- );
- }
- }
- },
- {
- name: "assessment_task_id",
- label: "Unit of Assessment",
- options: {
- filter: true,
- setCellHeaderProps: () => { return { width:"170px" } },
- setCellProps: () => { return { width:"140px" } },
- customBodyRender: (atId) => {
- const assessmentTask = assessmentTasks.find(at => at.assessment_task_id === atId);
- return <>{assessmentTask.unit_of_assessment ? "Team" : "Individual"}>;
- }
- }
- },
- {
- name: "completed_by_role_id",
- label: "Completed By",
- options: {
- filter: true,
- setCellHeaderProps: () => { return { width:"140px" } },
- setCellProps: () => { return { width:"140px" } },
- customBodyRender: (roleId) => {
- return <>{roleId === 5 ? "Student" : "TA/Instructor"}>;
- }
- }
- },
- {
- name: "assessment_task_id",
- label: "View",
- options: {
- filter: false,
- sort: false,
- setCellHeaderProps: () => { return { align:"center", width:"100px", className:"button-column-alignment" } },
- setCellProps: () => { return { align:"center", width:"100px", className:"button-column-alignment" } },
- customBodyRender: (atId) => {
- return (
-
-
{
- navbar.setAssessmentTaskInstructions(assessmentTasks, atId, completedAssessments, { readOnly: true });
+ const columns = [
+ {
+ name: "assessment_task_name",
+ label: "Task Name",
+ options: {
+ filter: true,
+ setCellHeaderProps: () => { return { width:"250px" } },
+ setCellProps: () => { return { width:"250px" } },
+ }
+ },
+ {
+ name: "initial_time",
+ label: "Initial Time",
+ options: {
+ filter: true,
+ setCellHeaderProps: () => { return { width:"150px" } },
+ setCellProps: () => { return { width:"150px" } },
+ customBodyRender: (initial_time) => {
+ return(
+ <>
+ {initial_time ? getHumanReadableDueDate(initial_time) : "N/A"}
+ >
+ );
+ }
+ }
+ },
+ {
+ name: "last_update",
+ label: "Last Update",
+ options: {
+ filter: true,
+ setCellHeaderProps: () => { return { width:"150px" } },
+ setCellProps: () => { return { width:"150px" } },
+ customBodyRender: (last_update) => {
+ return(
+ <>
+ {last_update ? getHumanReadableDueDate(last_update) : "N/A"}
+ >
+ );
+ }
+ }
+ },
+ {
+ name: "assessment_task_id",
+ label: "Unit of Assessment",
+ options: {
+ filter: true,
+ setCellHeaderProps: () => { return { width:"170px" } },
+ setCellProps: () => { return { width:"140px" } },
+ customBodyRender: (atId) => {
+ const assessmentTask = assessmentTasks.find(at => at.assessment_task_id === atId);
+ if (assessmentTask === undefined) {
+ return <>UNDEFINED>
+ }
+ return <>{assessmentTask.unit_of_assessment ? "Team" : "Individual"}>;
+ }
+ }
+ },
+ {
+ name: "completed_by_role_id",
+ label: "Completed By",
+ options: {
+ filter: true,
+ setCellHeaderProps: () => { return { width:"140px" } },
+ setCellProps: () => { return { width:"140px" } },
+ customBodyRender: (roleId) => {
+ return <>{roleId === 5 ? "Student" : "TA/Instructor"}>;
+ }
+ }
+ },
+ {
+ name: "assessment_task_id",
+ label: "View",
+ options: {
+ filter: false,
+ sort: false,
+ setCellHeaderProps: () => { return { align:"center", width:"100px", className:"button-column-alignment" } },
+ setCellProps: () => { return { align:"center", width:"100px", className:"button-column-alignment" } },
+ customBodyRender: (atId) => {
+ return (
+
+ {
var singluarCompletedAssessment = null;
if (completedAssessments) {
- singluarCompletedAssessment = completedAssessments.find(completedAssessment => completedAssessment.assessment_task_id === atId) ?? null;
+ singluarCompletedAssessment
+ = completedAssessments.find(
+ completedAssessment => completedAssessment.assessment_task_id === atId
+ ) ?? null;
}
genericResourcePOST(
`/rating`,
@@ -106,39 +111,44 @@ class ViewCompletedAssessmentTasks extends Component {
"user_id" : singluarCompletedAssessment.user_id,
"completed_assessment_id": singluarCompletedAssessment.completed_assessment_id,
}),
- );
- }}
- aria-label="completedAssessmentTasksViewIconButton"
- >
-
-
-
- )
-
- }
- }
- },
- ];
+ );
+ this.props.navbar.setAssessmentTaskInstructions(
+ assessmentTasks,
+ atId,
+ completedAssessments,
+ { readOnly: true, skipInstructions: true }
+ );
+ }}
+ aria-label="completedAssessmentTasksViewIconButton"
+ >
+
+
+
+ )
+ }
+ }
+ },
+ ];
- const options = {
- onRowsDelete: false,
- download: false,
- print: false,
- viewColumns: false,
- selectableRows: "none",
- selectableRowsHeader: false,
- responsive: "vertical",
- tableBodyMaxHeight: "21rem"
- };
+ const options = {
+ onRowsDelete: false,
+ download: false,
+ print: false,
+ viewColumns: false,
+ selectableRows: "none",
+ selectableRowsHeader: false,
+ responsive: "vertical",
+ tableBodyMaxHeight: "21rem"
+ };
- return (
-
- )
- }
+ return (
+
+ )
+ }
}
-export default ViewCompletedAssessmentTasks;
\ No newline at end of file
+export default ViewCompletedAssessmentTasks;
diff --git a/FrontEndReact/src/View/Student/View/StudentViewTeams.js b/FrontEndReact/src/View/Student/View/StudentViewTeams.js
index cb1d7fed0..02ae67347 100644
--- a/FrontEndReact/src/View/Student/View/StudentViewTeams.js
+++ b/FrontEndReact/src/View/Student/View/StudentViewTeams.js
@@ -23,13 +23,14 @@ class StudentViewTeams extends Component {
var navbar = this.props.navbar;
var state = navbar.state;
var chosenCourse = state.chosenCourse;
+ var chosenCourseId = chosenCourse["course_id"];
genericResourceGET(
- `/team_by_user?course_id=${chosenCourse["course_id"]}`, "teams", this);
+ `/team_by_user?course_id=${chosenCourseId}`, "teams", this);
var url = (
chosenCourse["use_tas"] ?
- `/user?course_id=${chosenCourse["course_id"]}&role_id=4` :
+ `/user?course_id=${chosenCourseId}&role_id=4` :
`/user?uid=${chosenCourse["admin_id"]}`
);
@@ -73,4 +74,4 @@ class StudentViewTeams extends Component {
}
}
-export default StudentViewTeams;
\ No newline at end of file
+export default StudentViewTeams;
diff --git a/FrontEndReact/src/View/Student/View/ViewTeams.js b/FrontEndReact/src/View/Student/View/ViewTeams.js
index 909df27e3..9a84b665d 100644
--- a/FrontEndReact/src/View/Student/View/ViewTeams.js
+++ b/FrontEndReact/src/View/Student/View/ViewTeams.js
@@ -3,79 +3,89 @@ import 'bootstrap/dist/css/bootstrap.css';
import CustomDataTable from "../../Components/CustomDataTable";
import { getHumanReadableDueDate } from "../../../utility";
-
-
class ViewTeams extends Component{
- render() {
- var teams = this.props.teams;
-
- var users = this.props.users;
-
- var navbar = this.props.navbar;
+ render() {
+ var teams = this.props.teams;
+ var users = this.props.users;
+ var navbar = this.props.navbar;
- const columns = [
- {
- name: "team_name",
- label: "Team Name",
- options: {
- filter: true,
- setCellHeaderProps: () => { return { width:"230px" } },
- setCellProps: () => { return { width:"230px" } },
- }
- },
- {
- name: "observer_id",
- label: navbar.state.chosenCourse["use_tas"] ? "TA Name" : "Instructor Name",
- options: {
- filter: true,
- setCellHeaderProps: () => { return { width:"230px" } },
- setCellProps: () => { return { width:"230px" } },
- customBodyRender: (observerId) => {
- return(
-
{users[observerId]}
- )
- }
- }
- },
- {
- name: "date_created",
- label: "Date Created",
- options: {
- filter: true,
- setCellHeaderProps: () => { return { width:"160px" } },
- setCellProps: () => { return { width:"160px" } },
- customBodyRender: (date_created) => {
- let dateCreatedString = getHumanReadableDueDate(date_created);
+ const columns = [
+ {
+ name: "team_name",
+ label: "Team Name",
+ options: {
+ filter: true,
+ setCellHeaderProps: () => { return { width:"230px" } },
+ setCellProps: () => { return { width:"230px" } },
+ }
+ },
+ {
+ name: "observer_id",
+ label: navbar.state.chosenCourse["use_tas"] ? "TA Name" : "Instructor Name",
+ options: {
+ filter: true,
+ setCellHeaderProps: () => { return { width:"230px" } },
+ setCellProps: () => { return { width:"230px" } },
+ customBodyRender: (observerId) => {
+ return(
+
{users[observerId]}
+ )
+ }
+ }
+ },
+ {
+ name: "team_users",
+ label: "Members",
+ options: {
+ filter: true,
+ setCellHeaderProps: () => { return { width:"230px" } },
+ setCellProps: () => { return { width:"230px" } },
+ customBodyRender: (user) => {
+ return(
+ <>{user + " "}>
+ );
+ }
+ },
+ },
+ {
+ name: "date_created",
+ label: "Date Created",
+ options: {
+ filter: true,
+ setCellHeaderProps: () => { return { width:"160px" } },
+ setCellProps: () => { return { width:"160px" } },
+ customBodyRender: (date_created) => {
+ let dateCreatedString = getHumanReadableDueDate(date_created);
- return(
-
- {date_created ? dateCreatedString : "N/A"}
-
- )
- }
- }
- },
- ];
+ return(
+
+ {date_created ? dateCreatedString : "N/A"}
+
+ )
+ }
+ }
+ },
+ ];
- const options = {
- onRowsDelete: false,
- download: false,
- print: false,
- viewColumns: false,
- selectableRows: "none",
- selectableRowsHeader: false,
- responsive: "vertical",
- tableBodyMaxHeight: "21rem"
- };
+ const options = {
+ onRowsDelete: false,
+ download: false,
+ print: false,
+ viewColumns: false,
+ selectableRows: "none",
+ selectableRowsHeader: false,
+ responsive: "vertical",
+ tableBodyMaxHeight: "21rem"
+ };
- return (
-
- )
- }
+ return (
+
+ )
+ }
}
-export default ViewTeams;
\ No newline at end of file
+export default ViewTeams;
diff --git a/README.md b/README.md
index acdfa0f07..ccc979314 100644
--- a/README.md
+++ b/README.md
@@ -8,360 +8,251 @@ research-based or custom rubrics. Instructors can email
students their results, as well as download the data
for analysis.
+# Setup
+The following shows how to get SkillBuilder running on your operating system.
-## SkillBuilder is implemented in three parts: ##
+## Requirements
-- A Back End Flask server.
+The following technologies are required:
+1. `Python >= 3.12`
+2. `Redis`
+3. `Docker/Docker Desktop`
+4. `Node >= v21.6.1`
-- A Caching Redis server.
+Find your operating system below and follow the instructions
+on installing them.
-- A Front End React server.
+### Linux
+#### Debian/Ubuntu (and its derivatives)
+1. Perform any system upgrades.
-## Setting up and running with Docker and Docker Compose: ##
+```
+sudo apt update -y
+sudo apt upgrade -y
+```
-- UPDATE: Using Docker and Docker Compose should become the sole
- method for running this application locally as it solves
- dependency issues across all platforms! Also makes developing
- easier as there are now only two commands to worry about.
+2. Install `Python3`:
+```
+sudo apt install python3
+python3 --version
+```
-- Follow the link for instructions on downloading Docker Desktop:
- https://www.docker.com/products/docker-desktop/
+Ensure that the version is `>= 3.12`.
-- NOTE: If you have an intel chip with Windows OS, you will need
- to go to the following link to install Docker Desktop:
- https://docs.docker.com/desktop/install/windows-install/
+*Note*: Debian uses the last _stable_ release of Python (which is not 3.12), but
+from testing, it seems to work just fine.
-- NOTE: Make sure that there are no running frontend,
- redis, or backend processes as there will be port
- conflicts. To view if you have processes running
- on important ports, run the following and expect
- no output:
+3. Install `Redis`:
- lsof -i :3000,5050,6379
-
- If output, there is a chance you still have processes
- running and you need to use the following command to
- kill them off:
+Using the following link to install:
- kill
-
- There is a chance that your OS has an important process
- running on one of these ports that should not be terminated.
- In that case, change the port for conflicting processes in the
- compose.yml file. Make sure that you also update changed
- ports in the frontend or backend .env and anywhere else
- needed!
+https://redis.io/docs/latest/operate/oss_and_stack/install/install-redis/install-redis-on-linux/
- Step 1:
- After following the instructions, ensure you have Docker
- Desktop open and running.
+*Note*: Ubuntu and Debian typically use `systemctl` as the init system, but if using
+something different, the docs will not cover those.
- Step 2:
- Open a new terminal and navigate to where you have this
- repository cloned.
+4. Install `Node`:
- Step 3:
- Run the following command to ensure you have docker running:
+```
+sudo apt install nodejs
+node -v
+```
- docker ps
+5. Install Docker/Docker Desktop:
- Step 4:
- Run the following command to build the images:
+Use the following link for the instuctions for Ubuntu:
- docker compose build
-
- NOTE: To rebuild with new changes applied and ignore cached
- build run the following:
+https://docs.docker.com/desktop/setup/install/linux/ubuntu/
- docker compose build --no-cache
+Use the following link for the instuctions for Debian:
- NOTE: To view all of the build logs instead of the default
- summary run the following:
+https://docs.docker.com/desktop/setup/install/linux/debian/
- docker compose build --process=plain
+### MacOS
- Step 5:
- Run the following command to run containers from the images:
+MacOS will require some kind of package manager (this document will
+use `homebrew`).
- docker compose up
+You can find `homebrew` here: https://brew.sh/
- Step 6:
- Open a browser with the link http://localhost:3000 to see the frontend.
+1. Install `Python3`
+You can find the downloads here:
+https://www.python.org/downloads/macos/
-## REQUIREMENTS: ##
+2. Install `Redis`
-- Python 3.12 and up.
+```
+brew install redis
+```
-- MySQL-Server.
+3. Install `Node`
-- Homebrew 4.2.18 and up.
+Either download prebuilt binaries directly, or use a package manager:
-- Redis 7.2.4 and up.
+https://nodejs.org/en/download/package-manager
-- Node.js v21.6.1 and up.
+4. Install Docker/Docker Desktop
-NOTE:
+The following link will walk you through it:
-- You WILL encounter issues when running both the
-Back End and Front End servers if you do NOT have
-installed the REQUIRED versions of Python and
-Node.js.
+https://docs.docker.com/desktop/setup/install/mac-install/
-NOTE:
+### Windows
-- Linux, Mac, and WSL Developers use `python3`.
+Running this project on bare metal Windows is no longer supported.
+You will need to get WSL (Windows Subsystem for Linux) or preferably WSL2.
-- WINDOWS DEVELOPERS ARE NO LONGER SUPPORTED.
+The following shows you how to set it up:
+https://learn.microsoft.com/en-us/windows/wsl/install
-## Setting up the MySQL Environment: ##
+Once this is install and set up, open Windows Terminal, Powershell, Command Prompt
+(or whatever terminal emulator you use) and do:
-- Run the following command to install MySQL-Server
-on Linux:
+```
+wsl
+```
- sudo apt install mysql-server
+If this is working correctly, follow the installation instructions in the *Linux*
+section of this README to get all dependencies.
-- Run the following command to install MySQL-Server
-on MacOS:
+## Running Rubricapp in a Docker container
- brew install mysql
+1. Perform a build:
-- Run the following command to start MySQL-Server
-on MacOS:
+```
+docker compose build
+```
- brew services start mysql
+This step is needed for whenever Docker files are modified.
-- Run the following command to start MySQL-Server
-in a new terminal:
+_Note_: Docker will cache during build time. If you need to rebuild without the
+cache, run:
- sudo mysql -u root
+```
+docker compose build --no-cache
+```
-- Next use these commands to create an account
-named skillbuilder and set the password to
-"WasPogil1#"
+2. To run the container, do:
- CREATE DATABASE account;
- CREATE USER 'skillbuilder'@'localhost' IDENTIFIED BY 'WasPogil1#';
- GRANT ALL PRIVILEGES ON *.* TO 'skillbuilder'@'localhost';
- FLUSH PRIVILEGES;
- exit;
+```
+docker compose up
+```
-NOTE:
+_Note_: if changes are required for the database, you can reset the database with:
-- The password should be changed for deployment.
+```
+docker compose down -v
+```
-- Once this is done, you can use: `setupEnv.py` as normal
-to create the database. If for any reason you want to
-access the database directly, run the following command:
+When the front end is finished compiling, it should show a link, namely: `http://localhost:3000`.
+Simply open this link in your browser and use an appropriate login.
- mysql -u skillbuilder -p
+# Not using Docker
-and then type the password.
+You can also run rubricapp without Docker, but you will need to manually run the setup yourself.
-## Installing requirements ##
+1. Create a virtual environment
-- Follow the link for instructions on downloading Python:
+```
+python3 -m venv
+source /bin/activate
+```
- https://www.python.org/downloads/
+This is where all of the Python dependencies will be stored instead of being
+stored globally on your system.
-- Follow the link for instructions on downloading Node.js:
+2. Start Redis
- https://nodejs.org/en/download
+Enable the Redis service using your appropriate `init system` (`systemctl` in this example).
-- Follow the link for instructions on downloading brew:
+```
+systemctl start redis
+```
- https://brew.sh/
+Make sure that it is running:
-- Once installed, run the following command with Homebrew
- to install redis:
+```
+systemctl status redis
+```
- brew install redis
+3. Launch the backend:
+```
+user@/(project root)$ cd BackendFlask
+user@/(project root)/BackendFlask$ python3 ./setupEnv.py -irds
+```
+The setup flags are as follows:
+* `-i, --install` - install all depencencies
+* `-r, --reset` - reset the database
+* `-d, --demo` - load demo data into the database
+* `-s, --start` - start the backend server
-## Setting up the Back End environment: ##
+Later iterations of using `setupEnv.py` only requires the `-s` flag
+(unless new depencencies are added or if the database needs to be reset etc).
-- Follow the instructions for setting up the virtual environment:
-
- Step 1:
- Ensure you are in the BackEndFlask directory by running
- the command:
+4. Launch the Frontend Server
- cd BackEndFlask
+```
+user@/(project root)$ cd FrontendReact
+user@/(project root)/FrontendReact$ npm install # only do this once
+user@/(project root)/FrontendReact$ npm start
+```
- Step 2:
- Create the virtual environment by running the command:
+This will launch the server on port 3000. Access it by navigating to `http://localhost:3000` in your browser and logging in with appropriate credentials.
- python3 -m venv BackEndFlaskVenv
+# Other
- Step 3:
- Activate the virtual environment by running the command:
+If you are testing with adding students/TAs/admins, it may be time consuming to
+manually do it via the website. There is a script that will automatically insert new
+users into the database straight from the command line. It is important to note
+that this script only works if the backend _is currently running inside docker_.
- source BackEndFlaskVenv/bin/activate
+Run this script with:
- To Deactivate the virtual environment, run the command:
+```
+./dbinsert.sh
+```
- deactivate
+Run this and follow the on-screen instructions.
- To Remove the virtual environment, run the command:
+# Troubleshooting
- rm -r BackEndFlaskVenv
+## Redis issues
-- In order to setup the environment for the first time,
- you will need to be in the `/rubricapp/BackEndFlask/`
- directory and run the following command:
+If it does not start correctly, there could be a multitude of reasons. I suggest
+using `journalctl` to investigate it (systemctl will give out the full command).
- python3 setupEnv.py -id
+But a good starting point is seeing if it is already running:
-- This command will install all the requirements from
- requirements.txt, create a new database, and load
- the database with demo data.
+```
+ps aux | grep redis
+```
-Flag Meanings:
+This will give the PIDs of all processess with `redis` in its name. Try killing them
+with `kill ..., ` and then rerunning `systemctl start redis`.
-- `-i` install
-- `-d` demo
+_Note_: if `redis` is not considered a service, try using `redis-server` or `redis-server.service`.
-NOTE:
-- If you DO NOT run the above command with the
- `-i` and `-d` flags once, then the Back End server
- WILL NOT be initialized properly. If the Back End
- server is NOT initialized properly, then the Back
- End server WILL NOT run. IF the Back End server
- is NOT running, then the Front End server WILL NOT
- run properly either.
+## Port conflicts
-- In the case where you want to restart with a fresh
- new database, add the flag `-r` to reset the existing
- database. You WILL then have to rerun the command with
- the `-d` flag to load demo data.
+The backend runs on port 5000 and the frontend runs on port 3000. You may already have processes running
+on those ports. If this is the case, you will have conflicts and the server(s) will not run normally.
+You can check what is running on those ports with:
+```
+lsof -i :5000
+lsof -i :3000
+```
-## Setting up the Front End environment: ##
-- Follow the link for instructions on downloading Node.js:
+If any output appears here, you may either want to kill them with `kill`, or run those processes on different ports.
- https://nodejs.org/en/download
-- In order to install the required packages you WILL need
- to be in the directory `/rubricapp/FrontEndReact/`.
-- Inside the Front End React directory run the following
- command to install all the Node packages for the project:
-
- npm install
-
-NOTE:
-- If you run `npm install` outside of the
- `/rubricapp/FrontEndReact/` directory, it WILL cause
- issues.
-
-- In the case where you run `npm install` outside
- of the `/rubricapp/FrontEndReact/` directory,
- simply remove the created files `package.json` and
- `package-lock.json` and the directory `node_modules`.
- Ensure that you have correctly changed the current
- working directory to `/rubricapp/FrontEndReact/`
- before attempting to run the command to install
- the Node packages.
-
-
-
-## Running the Servers after setup: ##
-
-NOTE:
-
-- You WILL need to run the Back End server first,
- the Redis server second, then the Front End server
- third.
-
-- You WILL need to run the Back End, Redis, and
- Front End servers in different terminal windows.
-
-
-
-## Running the Back End server of the application: ##
-- Use the following command for running the Back End
- server in the `/rubricapp/BackEndFlask/` directory
- during regular use:
-
- python3 setupEnv.py -s
-
-Flag meaning:
-
-- `-s` start
-
-
-
-## Running the Redis server: ##
-
-- Use the following command for running the Redis server:
-
- brew services start redis
-
-NOTE:
-- Run the following command to restart redis with
- Homebrew:
-
- brew services restart redis
-
-- Run the following command to stop redis with
- Homewbrew:
-
- brew services stop redis
-
-
-
-## Running the Front End server of the application: ##
-
-- Use the following command for running the Front End
- Server in the `/rubricapp/FrontEndReact/` directory:
-
- npm start
-
-- This command runs the Front End server in development mode.
- Open http://localhost:3000 or http://127.0.0.1:3000 to view
- it in your browser.
-
-- Any changes made in the `/rubricapp/FrontEndReact/`
- directory will be caught by the running Front End
- server, thus rerendering any opened tabs in your
- browser.
-
-- You will also be able to see any compile warnings
- and errors in the console.
-
-
-
-## Running Pytest: ##
-
-- For running pytests on the Back End server
- you will use the following command:
-
- python3 setupEnv.py -t
-
-Flag meaning:
-
-- `-t` test
-
-
-
-## Running Jest tests: ##
-
-- For running Jest tests on the Front End server
- you will use the following command:
-
- npm test
-
-- This command launches the test runner in the interactive
- watch mode. Make sure the version of react is
- 'react-scripts@0.3.0' or higher.
-
-- Here is a link for learning more information about running tests:
-
- https://facebook.github.io/create-react-app/docs/running-tests
diff --git a/README.old b/README.old
new file mode 100644
index 000000000..e58c1873e
--- /dev/null
+++ b/README.old
@@ -0,0 +1,372 @@
+# SkillBuilder
+
+A web application for evaluating students' professional
+skills, such as teamwork and communication. The purpose
+of the SkillBuilder application is to allow instructors
+to assess teams of students in real-time using
+research-based or custom rubrics. Instructors can email
+students their results, as well as download the data
+for analysis.
+
+
+
+## SkillBuilder is implemented in three parts: ##
+
+- A Back End Flask server.
+
+- A Caching Redis server.
+
+- A Front End React server.
+
+
+
+## Setting up and running with Docker and Docker Compose: ##
+
+- UPDATE: Using Docker and Docker Compose should become the sole
+ method for running this application locally as it solves
+ dependency issues across all platforms! Also makes developing
+ easier as there are now only two commands to worry about.
+
+- Follow the link for instructions on downloading Docker Desktop:
+ https://www.docker.com/products/docker-desktop/
+
+- NOTE: If you have an intel chip with Windows OS, you will need
+ to go to the following link to install Docker Desktop:
+ https://docs.docker.com/desktop/install/windows-install/
+
+- NOTE: Make sure that there are no running frontend,
+ redis, or backend processes as there will be port
+ conflicts. To view if you have processes running
+ on important ports, run the following and expect
+ no output:
+
+ lsof -i :3000,5050,6379
+
+ If output, there is a chance you still have processes
+ running and you need to use the following command to
+ kill them off:
+
+ kill
+
+ or optionally, send with a forced kill (not recommended as it does
+ not allow the process to shut down gracefully).
+
+ sudo kill -9
+
+ There is a chance that your OS has an important process
+ running on one of these ports that should not be terminated.
+ In that case, change the port for conflicting processes in the
+ compose.yml file. Make sure that you also update changed
+ ports in the frontend or backend .env and anywhere else
+ needed!
+
+ Step 1:
+ After following the instructions, ensure you have Docker
+ Desktop open and running.
+
+ Step 2:
+ Open a new terminal and navigate to where you have this
+ repository cloned.
+
+ Step 3:
+ Run the following command to ensure you have docker running:
+
+ docker ps
+
+ Step 4:
+ Run the following command to build the images:
+
+ docker compose build
+
+ NOTE: To rebuild with new changes applied and ignore cached
+ build run the following:
+
+ docker compose build --no-cache
+
+ NOTE: To view all of the build logs instead of the default
+ summary run the following:
+
+ docker compose build --process=plain
+
+ Step 5:
+ Run the following command to run containers from the images:
+
+ docker compose up
+
+ Step 6:
+ Open a browser with the link http://localhost:3000 to see the frontend and log in
+ with one of the demo students/TAs/admins.
+
+
+## REQUIREMENTS: ##
+
+- Python 3.12 and up.
+
+- MySQL-Server.
+
+- Homebrew 4.2.18 and up.
+
+- Redis 7.2.4 and up.
+
+- Node.js v21.6.1 and up.
+
+NOTE:
+
+- You WILL encounter issues when running both the
+Back End and Front End servers if you do NOT have
+installed the REQUIRED versions of Python and
+Node.js.
+
+NOTE:
+
+- Linux, Mac, and WSL Developers use `python3`.
+
+- WINDOWS DEVELOPERS ARE NO LONGER SUPPORTED.
+
+
+## Setting up the MySQL Environment: ##
+
+- Run the following command to install MySQL-Server
+on Linux:
+
+ sudo apt install mysql-server
+
+- Run the following command to install MySQL-Server
+on MacOS:
+
+ brew install mysql
+
+- Run the following command to start MySQL-Server
+on MacOS:
+
+ brew services start mysql
+
+- Run the following command to start MySQL-Server
+in a new terminal:
+
+ sudo mysql -u root
+
+- Next use these commands to create an account
+named skillbuilder and set the password to
+"WasPogil1#"
+
+ CREATE DATABASE account;
+ CREATE USER 'skillbuilder'@'localhost' IDENTIFIED BY 'WasPogil1#';
+ GRANT ALL PRIVILEGES ON *.* TO 'skillbuilder'@'localhost';
+ FLUSH PRIVILEGES;
+ exit;
+
+NOTE:
+
+- The password should be changed for deployment.
+
+- Once this is done, you can use: `setupEnv.py` as normal
+to create the database. If for any reason you want to
+access the database directly, run the following command:
+
+ mysql -u skillbuilder -p
+
+and then type the password.
+
+## Installing requirements ##
+
+- Follow the link for instructions on downloading Python:
+
+ https://www.python.org/downloads/
+
+- Follow the link for instructions on downloading Node.js:
+
+ https://nodejs.org/en/download
+
+- Follow the link for instructions on downloading brew:
+
+ https://brew.sh/
+
+- Once installed, run the following command with Homebrew
+ to install redis:
+
+ brew install redis
+
+
+
+## Setting up the Back End environment: ##
+
+- Follow the instructions for setting up the virtual environment:
+
+ Step 1:
+ Ensure you are in the BackEndFlask directory by running
+ the command:
+
+ cd BackEndFlask
+
+ Step 2:
+ Create the virtual environment by running the command:
+
+ python3 -m venv BackEndFlaskVenv
+
+ Step 3:
+ Activate the virtual environment by running the command:
+
+ source BackEndFlaskVenv/bin/activate
+
+ To Deactivate the virtual environment, run the command:
+
+ deactivate
+
+ To Remove the virtual environment, run the command:
+
+ rm -r BackEndFlaskVenv
+
+- In order to setup the environment for the first time,
+ you will need to be in the `/rubricapp/BackEndFlask/`
+ directory and run the following command:
+
+ python3 setupEnv.py -id
+
+- This command will install all the requirements from
+ requirements.txt, create a new database, and load
+ the database with demo data.
+
+Flag Meanings:
+
+- `-i` install
+- `-d` demo
+
+NOTE:
+- If you DO NOT run the above command with the
+ `-i` and `-d` flags once, then the Back End server
+ WILL NOT be initialized properly. If the Back End
+ server is NOT initialized properly, then the Back
+ End server WILL NOT run. IF the Back End server
+ is NOT running, then the Front End server WILL NOT
+ run properly either.
+
+- In the case where you want to restart with a fresh
+ new database, add the flag `-r` to reset the existing
+ database. You WILL then have to rerun the command with
+ the `-d` flag to load demo data.
+
+
+
+## Setting up the Front End environment: ##
+- Follow the link for instructions on downloading Node.js:
+
+ https://nodejs.org/en/download
+
+- In order to install the required packages you WILL need
+ to be in the directory `/rubricapp/FrontEndReact/`.
+
+- Inside the Front End React directory run the following
+ command to install all the Node packages for the project:
+
+ npm install
+
+NOTE:
+- If you run `npm install` outside of the
+ `/rubricapp/FrontEndReact/` directory, it WILL cause
+ issues.
+
+- In the case where you run `npm install` outside
+ of the `/rubricapp/FrontEndReact/` directory,
+ simply remove the created files `package.json` and
+ `package-lock.json` and the directory `node_modules`.
+ Ensure that you have correctly changed the current
+ working directory to `/rubricapp/FrontEndReact/`
+ before attempting to run the command to install
+ the Node packages.
+
+
+
+## Running the Servers after setup: ##
+
+NOTE:
+
+- You WILL need to run the Back End server first,
+ the Redis server second, then the Front End server
+ third.
+
+- You WILL need to run the Back End, Redis, and
+ Front End servers in different terminal windows.
+
+
+
+## Running the Back End server of the application: ##
+- Use the following command for running the Back End
+ server in the `/rubricapp/BackEndFlask/` directory
+ during regular use:
+
+ python3 setupEnv.py -s
+
+Flag meaning:
+
+- `-s` start
+
+
+
+## Running the Redis server: ##
+
+- Use the following command for running the Redis server:
+
+ brew services start redis
+
+NOTE:
+- Run the following command to restart redis with
+ Homebrew:
+
+ brew services restart redis
+
+- Run the following command to stop redis with
+ Homewbrew:
+
+ brew services stop redis
+
+
+
+## Running the Front End server of the application: ##
+
+- Use the following command for running the Front End
+ Server in the `/rubricapp/FrontEndReact/` directory:
+
+ npm start
+
+- This command runs the Front End server in development mode.
+ Open http://localhost:3000 or http://127.0.0.1:3000 to view
+ it in your browser.
+
+- Any changes made in the `/rubricapp/FrontEndReact/`
+ directory will be caught by the running Front End
+ server, thus rerendering any opened tabs in your
+ browser.
+
+- You will also be able to see any compile warnings
+ and errors in the console.
+
+
+
+## Running Pytest: ##
+
+- For running pytests on the Back End server
+ you will use the following command:
+
+ python3 setupEnv.py -t
+
+Flag meaning:
+
+- `-t` test
+
+
+
+## Running Jest tests: ##
+
+- For running Jest tests on the Front End server
+ you will use the following command:
+
+ npm test
+
+- This command launches the test runner in the interactive
+ watch mode. Make sure the version of react is
+ 'react-scripts@0.3.0' or higher.
+
+- Here is a link for learning more information about running tests:
+
+ https://facebook.github.io/create-react-app/docs/running-tests
diff --git a/dbinsert.sh b/dbinsert.sh
new file mode 100755
index 000000000..8a10df196
--- /dev/null
+++ b/dbinsert.sh
@@ -0,0 +1,19 @@
+#!/bin/bash
+
+set -e
+
+function help() {
+ echo "This script is inteded to be ran *while* the backend is running in Docker."
+ echo -e "It will insert a new user into the DB so you don't have to do it in the website.\n"
+ echo "dbinsert.sh