diff --git a/.github/pull_request_template.md b/.github/pull_request_template.md
new file mode 100644
index 00000000..560ab073
--- /dev/null
+++ b/.github/pull_request_template.md
@@ -0,0 +1,30 @@
+## Overview
+
+
+## Details
+
+
+- Bulleted list with explanations
+
+## Testing
+
+- [ ] Added/updated unit tests
+- [ ] Tested edge cases
+- [ ] Manual testing (if needed)
+
+## Dependencies
+
+
+## Future Work
+
+
+## Additional Notes
+
diff --git a/README.md b/README.md
index 7dc59b27..fd32b215 100644
--- a/README.md
+++ b/README.md
@@ -4,8 +4,8 @@ Autograder for [BYU CS 240 Chess project](https://github.com/softwareconstructio
## Development and Contributing
-This project relies on TAs like you to maintain and adapt the program! Come join the team!
-Check out the [Contribution Guide](https://github.com/orgs/softwareconstruction240/projects/1/views/1?pane=issue&itemId=84732654&issue=softwareconstruction240%7Cautograder%7C448) to learn how to effectively contribute as a part of the Autograder Development Team!
+This project relies on TAs like you to maintain and adapt the program. Come join the team!
+Check out the [Contribution Guide](docs/CONTRIBUTING.md) to learn how to effectively contribute as a part of the Autograder Development Team.
Read the [Getting Started Guide](docs/getting-started/getting-started.md) to get the project set up on your machine for development.
diff --git a/docs/CONTRIBUTING.md b/docs/CONTRIBUTING.md
new file mode 100644
index 00000000..84e22022
--- /dev/null
+++ b/docs/CONTRIBUTING.md
@@ -0,0 +1,293 @@
+# Contribution Guide
+
+Hello there! Welcome to the CS 240 Autograder Repo. If you're new to the
+Autograder Development team, we're glad to have you here. The CS 240
+Autograder relies on TAs like you to maintain and adapt the codebase
+for our professors and students.
+
+This document will give you all the info you need to know to successfully
+contribute to the best Autograder on campus!
+
+## Table of Contents
+- Welcome (You already read that)
+- [New Contributors [Start here if you're new]](#new-contributors)
+- [Guiding Principles](#guiding-principles)
+- [Development Pipeline](#development-pipeline)
+ - [1: Issues](#1-issues)
+ - [When to Create Issue](#when-to-create-an-issue)
+ - [Creating an Issue](#creating-an-issue)
+ - [Working on an Issue](#working-on-an-issue)
+ - [2: Branches](#2-branches)
+ - [Creating a Branch](#creating-a-branch)
+ - [3: Making Changes](#3-making-changes)
+ - [Writing Good Commit Messages](#writing-good-commit-messages)
+ - [4: Pull Requests](#4-pull-requests)
+ - [Creating a Pull Request](#creating-a-pull-request)
+ - [Scope of a Pull Request](#scope-of-a-pull-request)
+ - [Reviewing a Pull Request](#reviewing-a-pull-request)
+ - [After Merging](#after-merging)
+- [About Page](#about-page)
+- [Reminder About Ownership](#reminder-about-ownership)
+
+## Guiding Principles
+
+- We are building production quality software that accurately generates academic scores for hundreds of students.
+- We are learning/practicing being participants on a small dev team.
+- We thrive with contributions from many diverse perspectives.
+- We serve fellow humans with divine purpose in this order:
+ 1. The Lord
+ 2. Class professors
+ 3. Class students
+
+## New Contributors
+New to the Autograder Development team and not sure how to get
+started? Try this:
+
+1. Finish reading this document
+2. Get your dev environment set up by following the [Getting Started Guide](getting-started/getting-started.md)
+3. Review the Sequence/Class Diagrams (_Coming soon_)
+4. Look through some of the code, and try writing documentation for undocumented code
+5. Find a section of under-tested code and add some unit tests
+6. Take a look through the GitHub repo's [Issues](https://github.com/softwareconstruction240/autograder/issues) page
+ and find one you like, especially (but not limited to) ones labeled
+ ["good first issue"](https://github.com/softwareconstruction240/autograder/issues?q=is%3Aopen+is%3Aissue+label%3A%22good+first+issue%22)
+
+Don't be afraid to submit a PR, and most importantly, just get sucked in!
+
+## Development Pipeline
+
+As a broad overview, all changes to the Autograder start as an issue. Each
+issue eventually gets a branch made to solve the issue. And each branch
+gets made into a pull request before becoming part of the main branch of code.
+
+### 1. Issues
+
+Issues help us track what needs to be done and who's working on what. You can pick an already
+existing issue to work on, or you can write your own.
+
+> [!TIP]
+> Ideally, you should first work on issues in the `On Deck` column of the
+[TA Project Board](https://github.com/orgs/softwareconstruction240/projects/1/views/9),
+> but you are welcome to pick any unassigned issue
+
+#### When to Create an Issue
+
+An issue generally represents "a single goal or task." Discussion and decisions about how to accomplish the task (and
+even if the task should be done) happens here. Usually, an issue should be fairly narrow in scope, so that it can be
+resolved with a single Pull Request (PR).
+
+Even when you're not sure if the task should be done, or how to go about it, go ahead and create an issue. The issue
+might be closed, but now that decision has been discussed, and the reasons for it are saved somewhere central in case
+they are relevant in the future.
+
+#### Creating an Issue
+- Create the issue from the [TA Projects Board](https://github.com/orgs/softwareconstruction240/projects/1)
+ - Click "add item" at the bottom of the `Todo` list
+ - Type `#autograder` to connect the issue to the Autograder
+ - Type a title and hit enter
+- Use a clear, descriptive title that uses one of these prefixes (including the colon):
+ - `Backend:` server side changes
+ - `Frontend:` client (web) side changes
+ - `Fullstack:` for issues that require front and backend changes
+ - `Docs:` changes to documentation (either markdown files or JSDocs/JavaDocs)
+ - `Tests:` adding or modifying tests
+ - `Dev:` changes to enhance the Autograder development experience
+- Provide a clear and complete PR description. Consider using the following sections:
+ - **Overview**: The two sentence of the key problem.
+ - **Discussion**: A brief history of the context or arguments related to the issue.
+ Provide enough context so others can understand the purpose.
+ - **Proposal**: Suggested ways the problem could be approached, solved, or implemented.
+ Include specific file/class/method names as appropriate.
+ - **Related Work**: Links to related issues, PRs, or other documentation.
+- Add labels as appropriate using the built-in picker.
+- Remember: Issues should be narrow in scope.
+
+#### Working on an Issue
+- Assign the issue to yourself before beginning work (this is how we know
+ who is working on what, and gives you a sort of ownership over the issue)
+- Create a new branch ([more info here](#2-branches))
+- If you find a new issue, file it separately (don't mix concerns)
+- Leave a comment from time to time with updates on your progress
+
+### 2. Branches
+Branches in `git` allow us to all work on separate things in the same codebase.
+You will do all your work in a branch.
+
+#### Creating a branch
+Create the branch directly from the issue so your work is linked.
+
+- Always branch from `main`
+ - (exceptions exist if you know what you're doing)
+- Use descriptive names that reflect what you're working on:
+ - `add-late-submission`
+ - `admin-display-verification-status`
+ - `server-communicator`
+ - `extract-service-logic-from-controllers`
+- If the issue name is clear and concise, the default branch name from clicking "Create a branch" from the issue page is
+ also fine. It usually looks something like `488-fullstack-add-code-coverage-for-unit-tests`
+- Use kebab-case (lowercase with hyphens)
+- Keep names concise but clear
+- One branch per issue (don't mix different features/fixes)
+
+### 3. Making Changes
+Now that you have a branch, you can start to code! Hurray! 🎉
+Here are important guidelines to follow:
+
+- Review and follow the Style Guide (_Coming Soon_)
+- Write tests for your code. All new features and functionality should have tests demonstrating correctness
+ - Update existing tests if you change functionality
+ - _New contributors: A great way to better understand the codebase is to try writing tests for existing code_
+- Keep commits focused and meaningful
+ - Each commit should represent one logical change
+ - Write clear commit messages that describe that change ([See guidelines](#writing-good-commit-messages))
+ - Commit frequently
+- Update documentation as you go
+ - Add JSDoc/JavaDoc comments to new code
+ - _New contributors: Another great way to learn the codebase is to document existing code_
+ - Update repo Markdown docs if needed
+ - Code should for the most part be self-documenting. If not, make sure to add inline comments
+- Push your code to GitHub at the end of each coding session. This lets other team members see how you're doing
+
+#### Writing Good Commit Messages
+- Start with an imperative statement that describes what the commit does:
+ - `add late submission validation`
+ - `fix grade calculation bug`
+ - `update setup instructions`
+ - `remove unused imports`
+ - `refactor test runner`
+ - `document API endpoints`
+- Use lowercase letters
+- Keep it concise but clear (aim for under 50 characters)
+- Bad examples:
+ - `changes` (too vague)
+ - `Added new feature` (past tense)
+ - `WIP` (uninformative)
+ - `Fix stuff` (too vague)
+
+For bigger changes, you can add more details after the first line (leave a blank line between the first
+line and the extra details).
+
+> [!TIP]
+> A good commit message lets other developers know what changed without having to look at the code!
+
+### 4. Pull Requests
+Pull requests are how you get your changes merged into the codebase.
+You create a pull request once you feel your changes are ready for review by other devs.
+You can also create a draft pull request if you would like some feedback on your code before then.
+
+![Pull Request Lifecycle Overview](https://docs.github.com/assets/images/help/repository/branching.png)
+
+#### Creating a Pull Request
+- Make sure you have pushed all changes to GitHub first
+- The title of your pull request should be simple, concise, and descriptive
+ - It should have a prefix just like an issue
+ - It can be basically the name of the branch
+ - Issue: `Frontend: refactor all server calls to one place`
+ - Branch: `refactor-server-calls-to-one-place`
+ - Pull Request: `Frontend: refactor server calls into ServerCommunicator`
+ - Ensure the PR
+ is [linked to the issue](https://docs.github.com/en/issues/tracking-your-work-with-issues/using-issues/linking-a-pull-request-to-an-issue)
+ it resolves, if any
+- Fill out the Pull Request template with enough detail for others to understand what
+ changed without having to read all the new code.
+- Make sure all GitHub actions pass:
+ - Your pull request will be blocked from merging if all tests don't pass
+- Move the connected issue into the `PR Submitted` column on the
+ [TA Project Board](https://github.com/orgs/softwareconstruction240/projects/1/views/9)
+- Request a review from other Autograder developers
+ - If you're changing an existing system, request a review from the developer that
+ wrote it initially, or is most familiar with that system
+ - You can request multiple reviewers, but you're only required to get one approval to merge
+
+#### Scope of a Pull Request
+- Pull Requests should represent a complete, reviewable unit of work
+- In most cases, a pull request from one issue
+ - Multiple issues in one PR are fine and encouraged when they depend on each other, or form a cohesive change
+- While there's no strict size limit, consider breaking up very large changes if:
+ - They touch multiple unrelated areas
+ - They're becoming difficult to review
+ - They could logically be shipped separately
+
+> [!TIP]
+> A good PR represents a complete feature or fix, but shouldn't try to solve everything at once!
+
+#### Reviewing a Pull Request
+A crucial part of this process is the code review. The repo has been set up so that _**no changes may be merged
+into main without the review of at least one other developer.**_ If someone has requested a review from you, please
+take some time to help out and ensure the Autograder has quality code.
+
+**As a Reviewer**
+- Look for:
+ - Code quality and style guide compliance
+ - Test coverage
+ - Potential bugs or edge cases
+ - Documentation completeness
+- Checkout the branch on your local machine and do some manual testing
+ - Specifically verify new/changed systems work. Try breaking it.
+ - Generally check other systems still work and haven't been broken
+ - (Student submissions on test student is most important)
+- Be constructive and kind in your feedback. We're all learning here
+- If changes are needed:
+ - Be specific about what needs to change
+ - Explain why the change is needed
+ - Suggest how to make the change if possible
+- Approve the PR when you're satisfied with all changes
+
+**As a Pull Request Author**
+- Respond to reviewer comments promptly
+- Be open to feedback and suggestions
+- Explain your decisions when asked
+- Make requested changes or explain why they shouldn't be made
+- Mark conversations as resolved _only_ once you have addressed the concern
+- Re-request review from key individuals
+- Thank reviewers for their time
+
+> [!IMPORTANT]
+> Once the pull request is approved and ready to merge, it is the responsibility and privilege of the author
+> (not the reviewer) to merge the request.
+
+> [!NOTE]
+> Once a pull request is merged to main, it does not immediately deploy to the live Autograder. Changes will
+> not be reflected in the live system until the head Autograder developer releases a new version of the system.
+
+#### After Merging
+Congrats! You just added code to the Autograder!
+
+Make sure you move your issue on the [TA Project Board](https://github.com/orgs/softwareconstruction240/projects/1/views/9)
+to the `Done` column. This will happen automatically if the PR was linked to issue it resolves when the PR was merged.
+
+Celebrate!
+
+## About Page
+A lot of time and effort goes into developing and maintaining the Autograder. Thank you!
+
+If you're new to the team, add yourself to the Autograder's [About Page](../src/main/resources/frontend/src/components/AboutPage.vue).
+(You can see the live one by doing the Konami Code anywhere on the Autograder front end.)
+
+Fill this component out and add it to the bottom of the current list of developers:
+```vue
+
+```
+Most TAs just link to their GitHub profile on their URL.
+
+Tenure should indicate when you worked as a CS 240 TA, not just as an Autograder Developer.
+
+Write a short sentence describing your work on the Autograder. You can update this in the future as you make more contributions.
+
+FA-icon is a font-awesome icon. Search through [Font Awesome's free icon collection](https://fontawesome.com/search?o=r&m=free)
+and choose one to represent you.
+
+## Reminder About Ownership
+As BYU employees writing code for our job as TAs, all code you contribute becomes the
+intellectual property of Brigham Young University.
+
+> Pursuant to law and university policy, **any work** (whether a Technical Work or a Creative Work) prepared by
+> University Personnel within the scope of their employment, without an express agreement specifying otherwise,
+> **is work for hire owned by the university**.
+>
+> — [BYU Intellectual Property Policy](https://policy.byu.edu/view/intellectual-property-policy) (emphasis added)
diff --git a/docs/getting-started/getting-started.md b/docs/getting-started/getting-started.md
index 3276d8a1..a58bb51f 100644
--- a/docs/getting-started/getting-started.md
+++ b/docs/getting-started/getting-started.md
@@ -1,5 +1,8 @@
# Getting Started
+> [!TIP]
+> Read through the [Contribution Guide](../CONTRIBUTING.md) before making contributions to the project.
+
## Pre-requisites
> [!IMPORTANT]
diff --git a/src/main/java/edu/byu/cs/autograder/score/Scorer.java b/src/main/java/edu/byu/cs/autograder/score/Scorer.java
index 50921373..73f80c42 100644
--- a/src/main/java/edu/byu/cs/autograder/score/Scorer.java
+++ b/src/main/java/edu/byu/cs/autograder/score/Scorer.java
@@ -431,11 +431,7 @@ public Submission generateSubmissionObject(Rubric rubric, CommitVerificationResu
Integer maxLateDays = DaoService.getConfigurationDao().getConfiguration(ConfigurationDao.Configuration.MAX_LATE_DAYS_TO_PENALIZE, Integer.class);
- if (numDaysLate >= maxLateDays)
- notes += " Late penalty maxed out at " + numDaysLate + " days late: -";
- else if (numDaysLate > 0)
- notes += " " + numDaysLate + " days late: -";
- notes += (int)(numDaysLate * PER_DAY_LATE_PENALTY * 100) + "% ";
+ notes = makeLatePenaltyNotes(numDaysLate, maxLateDays, notes);
ZonedDateTime handInDate = ScorerHelper.getHandInDateZoned(netId);
Submission.VerifiedStatus verifiedStatus;
@@ -467,6 +463,25 @@ else if (numDaysLate > 0)
);
}
+ private String makeLatePenaltyNotes(int numDaysLate, int maxLateDays, String origNotes) {
+ if (numDaysLate <= 0) {
+ return origNotes;
+ }
+
+ String penaltyPercentage = String.format("-%d%%", (int)(numDaysLate * PER_DAY_LATE_PENALTY * 100));
+ String lateNotes;
+ if (numDaysLate >= maxLateDays) {
+ lateNotes = "Late penalty maxed out: " + penaltyPercentage;
+ } else {
+ lateNotes = String.format("%d days late: %s", numDaysLate, penaltyPercentage);
+ }
+
+ if (origNotes == null || origNotes.isBlank()) {
+ return lateNotes;
+ }
+ return String.format("%s\n%s", origNotes, lateNotes);
+ }
+
private void sendToCanvas(int userId, int assignmentNum, CanvasRubricAssessment assessment, String notes)
throws GradingException {
sendToCanvas(userId, assignmentNum, assessment, notes, gradingContext.netId());
diff --git a/src/main/resources/frontend/getting-started.md b/src/main/resources/frontend/getting-started.md
new file mode 120000
index 00000000..324427e4
--- /dev/null
+++ b/src/main/resources/frontend/getting-started.md
@@ -0,0 +1 @@
+../../../../docs/getting-started/getting-started.md
\ No newline at end of file
diff --git a/src/main/resources/frontend/src/components/AboutPage.vue b/src/main/resources/frontend/src/components/AboutPage.vue
index 57e69044..4e7d4475 100644
--- a/src/main/resources/frontend/src/components/AboutPage.vue
+++ b/src/main/resources/frontend/src/components/AboutPage.vue
@@ -114,6 +114,10 @@ onUnmounted(() => {
tenure="Jan 2024-Aug 2024"
contributions="Wrote some systems that did pre-compiling verification of student code"
fa-icon="fa-solid fa-face-grin-squint-tears"/>
+
diff --git a/src/main/resources/frontend/src/network/ServerCommunicator.ts b/src/main/resources/frontend/src/network/ServerCommunicator.ts
index 2946e030..ee2bf7eb 100644
--- a/src/main/resources/frontend/src/network/ServerCommunicator.ts
+++ b/src/main/resources/frontend/src/network/ServerCommunicator.ts
@@ -31,13 +31,11 @@ export const ServerCommunicator = {
* returns nothing or responds with a non-2XX code
* @returns {Promise} Promise that resolves to the response data of type T
*/
-async function getRequestGuaranteed(endpoint: string, errorResponse: T): Promise {
- try {
- return await getRequest(endpoint, true)
- } catch (e) {
- return errorResponse
- }
+function getRequestGuaranteed(endpoint: string, errorResponse: T): Promise {
+ return getRequest(endpoint, true)
+ .catch(_error => Promise.resolve(errorResponse));
}
+
/**
* Makes a GET request to the specified endpoint.
* @template T - The type of the expected response (when expectResponse is true)
@@ -61,15 +59,12 @@ function getRequest(endpoint: string, expectResponse: false): Promise;
* @throws {ServerError} When the request fails (meaning the server returned a code other than 2XX)
* @throws {Error} when expectResponse is true but no response is received
*/
-function getRequest(endpoint: string, expectResponse?: true): Promise;
-async function getRequest(
+function getRequest(endpoint: string, expectResponse?: boolean): Promise;
+function getRequest(
endpoint: string,
expectResponse: boolean = true
): Promise {
- if (expectResponse) {
- return await doRequest("GET", endpoint, null, true);
- }
- return await doRequest("GET", endpoint, null, false);
+ return doRequest("GET", endpoint, null, expectResponse);
}
/**
@@ -111,17 +106,13 @@ function postRequest(endpoint: string, bodyObject: Object | null, expectResponse
* // Without response
* await postRequest('/api/logs', { event: 'action' }, false);
*/
-function postRequest(endpoint: string, bodyObject?: Object | null, expectResponse?: true): Promise;
-async function postRequest(
+function postRequest(endpoint: string, bodyObject?: Object | null, expectResponse?: boolean): Promise;
+function postRequest(
endpoint: string,
bodyObject: Object | null = null,
expectResponse: boolean = true
): Promise {
- if (expectResponse) {
- return await doRequest("POST", endpoint, bodyObject, true);
- }
- return await doRequest("POST", endpoint, bodyObject, false);
-
+ return doRequest("POST", endpoint, bodyObject, expectResponse);
}
/**
@@ -163,7 +154,7 @@ function patchRequest(endpoint: string, bodyObject: Object | null, expectRespons
* // Without response
* await patchRequest('/api/users/123/status', { status: 'active' }, false);
*/
-function patchRequest(endpoint: string, bodyObject?: Object | null, expectResponse?: true): Promise;
+function patchRequest(endpoint: string, bodyObject?: Object | null, expectResponse?: boolean): Promise;
async function patchRequest(
endpoint: string,
bodyObject: Object | null = null,
@@ -189,7 +180,7 @@ async function patchRequest(
* @throws {Error} When expectResponse is true but no response is received
* @internal
*/
-function doRequest(
+function doRequest(
method: string,
endpoint: string,
bodyObject: Object | null,
@@ -213,7 +204,7 @@ function doRequest(
method: string,
endpoint: string,
bodyObject?: Object | null,
- expectResponse?: true
+ expectResponse?: boolean
): Promise;
/**
* Internal method to make an HTTP request.
diff --git a/src/main/resources/frontend/src/network/ServerError.ts b/src/main/resources/frontend/src/network/ServerError.ts
index 81ad25c2..91a004d7 100644
--- a/src/main/resources/frontend/src/network/ServerError.ts
+++ b/src/main/resources/frontend/src/network/ServerError.ts
@@ -22,4 +22,4 @@ export class ServerError extends Error {
isHonorCodeViolation(): boolean { return this.status === 418; }
isUnprocessableEntity(): boolean { return this.status === 422; }
isInternalServerError(): boolean { return this.status === 500; }
-}
\ No newline at end of file
+}
diff --git a/src/main/resources/frontend/src/services/adminService.ts b/src/main/resources/frontend/src/services/adminService.ts
index e2a15d8c..b34531ea 100755
--- a/src/main/resources/frontend/src/services/adminService.ts
+++ b/src/main/resources/frontend/src/services/adminService.ts
@@ -2,38 +2,37 @@ import type {CanvasSection, Phase, Submission, User } from '@/types/types'
import type {Option} from "@/views/AdminView/Analytics.vue";
import { ServerCommunicator } from '@/network/ServerCommunicator'
-export const usersGet = async (): Promise => {
- return await ServerCommunicator.getRequestGuaranteed('/api/admin/users', [])
+export const usersGet = (): Promise => {
+ return ServerCommunicator.getRequestGuaranteed('/api/admin/users', [])
}
-export const submissionsForUserGet = async (netId: string): Promise => {
- return await ServerCommunicator.getRequestGuaranteed('/api/admin/submissions/student/' + netId, [])
+export const submissionsForUserGet = (netId: string): Promise => {
+ return ServerCommunicator.getRequestGuaranteed('/api/admin/submissions/student/' + netId, [])
}
-export const approveSubmissionPost = async (netId: string, phase: Phase, penalize: boolean) => {
- await ServerCommunicator.postRequest('/api/admin/submissions/approve',
- {
+export const approveSubmissionPost = (netId: string, phase: Phase, penalize: boolean) => {
+ return ServerCommunicator.postRequest('/api/admin/submissions/approve', {
netId,
phase,
penalize,
})
}
-export const submissionsLatestGet = async (batchSize?: number): Promise => {
+export const submissionsLatestGet = (batchSize?: number): Promise => {
batchSize = batchSize ? batchSize : -1
- return await ServerCommunicator.getRequestGuaranteed('/api/admin/submissions/latest/' + batchSize, [])
+ return ServerCommunicator.getRequestGuaranteed('/api/admin/submissions/latest/' + batchSize, [])
}
-export const testStudentModeGet = async (): Promise => {
- return await ServerCommunicator.getRequestGuaranteed('/api/admin/test_mode', null)
+export const testStudentModeGet = (): Promise => {
+ return ServerCommunicator.getRequestGuaranteed('/api/admin/test_mode', null)
}
type QueueStatusResponse = {
currentlyGrading: string[],
inQueue: string[]
}
-export const getQueueStatus = async (): Promise => {
- return await ServerCommunicator.getRequestGuaranteed(
+export const getQueueStatus = (): Promise => {
+ return ServerCommunicator.getRequestGuaranteed(
'/api/admin/submissions/active', {
currentlyGrading: [],
inQueue: []
@@ -56,6 +55,6 @@ export const honorCheckerZipGet = async (section: number): Promise => {
}
}
-export const sectionsGet = async (): Promise => {
- return await ServerCommunicator.getRequestGuaranteed('/api/admin/sections', [])
+export const sectionsGet = (): Promise => {
+ return ServerCommunicator.getRequestGuaranteed('/api/admin/sections', [])
}
diff --git a/src/main/resources/frontend/src/services/authService.ts b/src/main/resources/frontend/src/services/authService.ts
index 20194402..78360c7e 100644
--- a/src/main/resources/frontend/src/services/authService.ts
+++ b/src/main/resources/frontend/src/services/authService.ts
@@ -8,8 +8,8 @@ type MeResponse = {
repoUrl: string,
role: 'STUDENT' | 'ADMIN'
}
-export const meGet = async () => {
- return await ServerCommunicator.getRequestGuaranteed('/api/me', null)
+export const meGet = () => {
+ return ServerCommunicator.getRequestGuaranteed('/api/me', null)
}
export const loadUser = async () => {
@@ -20,6 +20,6 @@ export const loadUser = async () => {
useAuthStore().user = loggedInUser;
}
-export const logoutPost = async () => {
- await ServerCommunicator.postRequest( "/auth/logout", null, false)
+export const logoutPost = () => {
+ return ServerCommunicator.postRequest( "/auth/logout", null, false)
}
diff --git a/src/main/resources/frontend/src/services/configService.ts b/src/main/resources/frontend/src/services/configService.ts
index 7eff61e2..14137f58 100644
--- a/src/main/resources/frontend/src/services/configService.ts
+++ b/src/main/resources/frontend/src/services/configService.ts
@@ -4,32 +4,32 @@ import { useAuthStore } from '@/stores/auth'
import { ServerCommunicator } from '@/network/ServerCommunicator'
import { ServerError } from '@/network/ServerError'
-export const getConfig = async ():Promise => {
+export const getConfig = (): Promise => {
let endpoint = "/api"
if (useAuthStore().user?.role == 'ADMIN') {
endpoint += "/admin"
}
endpoint += "/config"
- return await ServerCommunicator.getRequest(endpoint)
+ return ServerCommunicator.getRequest(endpoint)
}
-export const setPenalties = async (maxLateDaysPenalized: number,
+export const setPenalties = (maxLateDaysPenalized: number,
gitCommitPenalty: number,
perDayLatePenalty: number,
linesChangedPerCommit: number,
clockForgivenessMinutes: number) => {
- await doSetConfigItem("POST", '/api/admin/config/penalties', {
- maxLateDaysPenalized: maxLateDaysPenalized,
- gitCommitPenalty: gitCommitPenalty,
- perDayLatePenalty: perDayLatePenalty,
- linesChangedPerCommit: linesChangedPerCommit,
- clockForgivenessMinutes: clockForgivenessMinutes
+ return doSetConfigItem("POST", '/api/admin/config/penalties', {
+ maxLateDaysPenalized,
+ gitCommitPenalty,
+ perDayLatePenalty,
+ linesChangedPerCommit,
+ clockForgivenessMinutes,
})
}
-export const setBanner = async (message: String, link: String, color: String, expirationTimestamp: String): Promise => {
- await doSetConfigItem("POST", '/api/admin/config/banner', {
+export const setBanner = (message: String, link: String, color: String, expirationTimestamp: String): Promise => {
+ return doSetConfigItem("POST", '/api/admin/config/banner', {
"bannerMessage": message,
"bannerLink": link,
"bannerColor": color,
@@ -38,32 +38,32 @@ export const setBanner = async (message: String, link: String, color: String, ex
);
}
-export const setLivePhases = async (phases: Array): Promise => {
- await doSetConfigItem("POST", '/api/admin/config/phases', {"phases": phases});
+export const setLivePhases = (phases: Array): Promise => {
+ return doSetConfigItem("POST", '/api/admin/config/phases', {"phases": phases});
}
-export const setGraderShutdown = async (shutdownTimestamp: string, shutdownWarningHours: number): Promise => {
+export const setGraderShutdown = (shutdownTimestamp: string, shutdownWarningHours: number): Promise => {
if (shutdownWarningHours < 0) shutdownWarningHours = 0
- await doSetConfigItem("POST", "/api/admin/config/phases/shutdown", {
+ return doSetConfigItem("POST", "/api/admin/config/phases/shutdown", {
"shutdownTimestamp": shutdownTimestamp,
"shutdownWarningMilliseconds": Math.trunc(shutdownWarningHours * 60 * 60 * 1000) // convert to milliseconds
})
}
-export const setCanvasCourseIds = async (): Promise => {
- await doSetConfigItem("GET", "/api/admin/config/courseIds", {});
+export const setCanvasCourseIds = (): Promise => {
+ return doSetConfigItem("GET", "/api/admin/config/courseIds", {});
}
-const convertRubricInfoToObj = (rubricInfo: Map>): object => {
- const obj: any = {};
+const convertRubricInfoToObj = (rubricInfo: Map>): Record> => {
+ const obj = {} as Record>;
rubricInfo.forEach((rubricTypeMap, phase) => {
obj[phase] = Object.fromEntries(rubricTypeMap.entries());
});
return obj;
}
-export const setCourseIds = async (
+export const setCourseIds = (
courseNumber: number,
assignmentIds: Map,
rubricInfo: Map>
@@ -73,7 +73,7 @@ export const setCourseIds = async (
"assignmentIds": Object.fromEntries(assignmentIds.entries()),
"rubricInfo": convertRubricInfoToObj(rubricInfo)
};
- await doSetConfigItem("POST", "/api/admin/config/courseIds", body);
+ return doSetConfigItem("POST", "/api/admin/config/courseIds", body);
}
const doSetConfigItem = async (method: string, path: string, body: Object): Promise => {
diff --git a/src/main/resources/frontend/src/services/submissionService.ts b/src/main/resources/frontend/src/services/submissionService.ts
index 9445bb95..e38571b2 100644
--- a/src/main/resources/frontend/src/services/submissionService.ts
+++ b/src/main/resources/frontend/src/services/submissionService.ts
@@ -2,21 +2,21 @@ import type {Submission} from "@/types/types";
import { Phase } from "@/types/types";
import { ServerCommunicator } from '@/network/ServerCommunicator'
-export const submissionsGet = async (phase: Phase | null): Promise => {
+export const submissionsGet = (phase: Phase | null): Promise => {
const endpoint: string = '/api/submission' + (phase === null ? "" : "/" + Phase[phase])
- return await ServerCommunicator.getRequestGuaranteed(endpoint, [])
+ return ServerCommunicator.getRequestGuaranteed(endpoint, [])
};
-export const lastSubmissionGet = async (): Promise => {
- return await ServerCommunicator.getRequestGuaranteed("/api/latest", null)
+export const lastSubmissionGet = (): Promise => {
+ return ServerCommunicator.getRequestGuaranteed("/api/latest", null)
};
-export const submissionPost = async (phase: Phase): Promise => {
- await ServerCommunicator.postRequest("/api/submit", { "phase": Phase[phase] }, false)
+export const submissionPost = (phase: Phase): Promise => {
+ return ServerCommunicator.postRequest("/api/submit", { "phase": Phase[phase] }, false)
}
-export const adminSubmissionPost = async (phase: Phase, repoUrl: String): Promise => {
- await ServerCommunicator.postRequest("/api/admin/submit", {
+export const adminSubmissionPost = (phase: Phase, repoUrl: String): Promise => {
+ return ServerCommunicator.postRequest("/api/admin/submit", {
"phase": Phase[phase],
"repoUrl": repoUrl
}, false)
@@ -29,6 +29,6 @@ export const submitGet = async (): Promise => {
return (await ServerCommunicator.getRequest("/api/submit")).inQueue
}
-export const reRunSubmissionsPost = async () => {
- await ServerCommunicator.postRequest("/api/admin/submissions/rerun")
+export const reRunSubmissionsPost = () => {
+ return ServerCommunicator.postRequest("/api/admin/submissions/rerun")
}
diff --git a/src/main/resources/frontend/src/services/userService.ts b/src/main/resources/frontend/src/services/userService.ts
index a9b88591..3a945d24 100644
--- a/src/main/resources/frontend/src/services/userService.ts
+++ b/src/main/resources/frontend/src/services/userService.ts
@@ -1,20 +1,20 @@
import type { RepoUpdate } from '@/types/types'
import { ServerCommunicator } from '@/network/ServerCommunicator'
-export const repoHistoryGet = async (netId: String): Promise => {
- return await ServerCommunicator.getRequestGuaranteed('/api/admin/repo/history?netId=' + netId, [])
+export const repoHistoryGet = (netId: String): Promise => {
+ return ServerCommunicator.getRequestGuaranteed('/api/admin/repo/history?netId=' + netId, [])
};
-export const studentUpdateRepoPatch = async (repoUrl: string): Promise => {
- await updateRepoPatch(repoUrl, '/api/repo')
+export const studentUpdateRepoPatch = (repoUrl: string): Promise => {
+ return updateRepoPatch(repoUrl, '/api/repo')
}
-export const adminUpdateRepoPatch = async (repoUrl: string, netId: String): Promise => {
- await updateRepoPatch(repoUrl, "/api/admin/repo/" + netId)
+export const adminUpdateRepoPatch = (repoUrl: string, netId: String): Promise => {
+ return updateRepoPatch(repoUrl, "/api/admin/repo/" + netId)
}
-const updateRepoPatch = async (repoUrl: string, endpoint: string): Promise => {
- await ServerCommunicator.patchRequest(endpoint, {
+const updateRepoPatch = (repoUrl: string, endpoint: string): Promise => {
+ return ServerCommunicator.patchRequest(endpoint, {
"repoUrl": repoUrl
}, false)
}
diff --git a/src/main/resources/frontend/src/stores/submissions.ts b/src/main/resources/frontend/src/stores/submissions.ts
index eaf8076f..6dea1625 100644
--- a/src/main/resources/frontend/src/stores/submissions.ts
+++ b/src/main/resources/frontend/src/stores/submissions.ts
@@ -21,9 +21,7 @@ export const useSubmissionStore = defineStore('submission', () => {
currentlyGrading.value = await submitGet();
}
- const getLastSubmission = async () => {
- return await lastSubmissionGet();
- }
+ const getLastSubmission = () => lastSubmissionGet();
return {
submissionsByPhase,