import axios, { AxiosInstance, AxiosResponse } from 'axios' import { errorInterceptor } from '@/util/interceptor' import { Credentials } from '@/store/modules/authentication' import { Assignment, Exam, Feedback, FeedbackComment, JSONWebToken, Statistics, StudentInfo, StudentInfoForListView, Submission, SubmissionNoType, SubmissionType, Subscription, Tutor, UserAccount } from '@/models' function getInstanceBaseUrl (): string { if (process.env.NODE_ENV === 'production') { return `${window.location.protocol}//${window.location.host}${window.location.pathname}`.replace(/\/+$/, '') } else { return 'http://localhost:8000/' } } let ax: AxiosInstance = axios.create({ baseURL: getInstanceBaseUrl() }) { let token = window.sessionStorage.getItem('token') if (token) { ax.defaults.headers['Authorization'] = `JWT ${token}` } } export async function registerTutor (credentials: Credentials): Promise<AxiosResponse<Tutor>> { return ax.post<Tutor>('/api/tutor/register/', credentials) } export async function fetchJWT (credentials: Credentials): Promise<JSONWebToken> { const token: string = (await ax.post('/api/get-token/', credentials)).data.token ax.defaults.headers['Authorization'] = `JWT ${token}` return { token } } export async function refreshJWT (oldToken: string): Promise<JSONWebToken> { const token: string = (await ax.post('/api/refresh-token/', { token: oldToken })).data.token ax.defaults.headers['Authorization'] = `JWT ${token}` return { token } } export async function fetchJWTTimeDelta (): Promise<number> { return (await ax.get('/api/jwt-time-delta/')).data.timeDelta } export async function fetchStudentSelfData (): Promise<StudentInfo> { return (await ax.get('/api/student-page/')).data } export async function fetchStudentSubmissions (): Promise<Array<Submission>> { return (await ax.get('/api/student-submissions/')).data } export async function fetchSubmissionFeedbackTests ({ pk }: {pk: string}): Promise<SubmissionNoType> { return (await ax.get(`/api/submission/${pk}/`)).data } export async function fetchAllStudents (): Promise<Array<StudentInfoForListView>> { const url = '/api/student/' return (await ax.get(url)).data } export async function fetchStudent ({ pk }: {pk: string}): Promise<StudentInfoForListView> { const url = `/api/student/${pk}/` return (await ax.get(url)).data } export async function fetchAllTutors (): Promise<Array<Tutor>> { const url = '/api/tutor/' return (await ax.get(url)).data } export async function fetchSubscriptions (): Promise<Array<Subscription>> { return (await ax.get('/api/subscription/')).data } export async function deactivateSubscription ({ pk }: {pk: string}): Promise<AxiosResponse<void>> { const url = `/api/subscription/${pk}/` return ax.delete(url) } export async function fetchSubscription (subscriptionPk: string): Promise<Subscription> { return (await ax.get(`/api/subscription/${subscriptionPk}/`)).data } export async function fetchAllFeedback (): Promise<Array<Feedback>> { const url = '/api/feedback/' return (await ax.get(url)).data } export async function fetchFeedback ({ ofSubmission }: {ofSubmission: string}): Promise<Feedback> { const url = `/api/feedback/${ofSubmission}/` return (await ax.get(url)).data } export async function fetchExamTypes (): Promise<Array<Exam>> { const url = `/api/examtype/` return (await ax.get(url)).data } export async function fetchStatistics (): Promise<Statistics> { const url = '/api/statistics/' return (await ax.get(url)).data } interface SubscriptionCreatePayload { queryType: Subscription.QueryTypeEnum queryKey?: string feedbackStage?: Subscription.FeedbackStageEnum } export async function subscribeTo (type: Subscription.QueryTypeEnum, key?: string, stage?: Subscription.FeedbackStageEnum): Promise<Subscription> { let data: SubscriptionCreatePayload = { queryType: type } if (key) { data.queryKey = key } if (stage) { data.feedbackStage = stage } return (await ax.post('/api/subscription/', data)).data } export async function createAssignment ( { subscription = undefined, subscriptionPk = '' }: {subscription?: Subscription, subscriptionPk?: string}): Promise<Assignment> { const data = { subscription: subscription ? subscription.pk : subscriptionPk } return (await ax.post(`/api/assignment/`, data)).data } export async function submitFeedbackForAssignment ({ feedback }: {feedback: Partial<Feedback>}): Promise<Feedback> { return (await ax.post('/api/feedback/', feedback)).data } export async function submitUpdatedFeedback ({ feedback }: {feedback: Feedback}): Promise<Feedback> { return (await ax.patch(`/api/feedback/${feedback.ofSubmission}/`, feedback)).data } export async function fetchSubmissionTypes (): Promise<Array<SubmissionType>> { const url = '/api/submissiontype/' return (await ax.get(url)).data } export async function fetchAllAssignments (): Promise<Array<Assignment>> { const url = '/api/assignment/' return (await ax.get(url)).data } export async function fetchActiveAssignments (): Promise<Assignment[]> { const url = '/api/assignment/active/' return (await ax.get(url)).data } export async function deleteAssignment ({ assignment }: {assignment: Assignment}): Promise<AxiosResponse<void>> { const url = `/api/assignment/${assignment.pk}/` return ax.delete(url) } export async function deleteAllActiveAssignments () { const url = '/api/assignment/active/' return ax.delete(url) } export async function deleteComment (comment: FeedbackComment): Promise<AxiosResponse<void>> { const url = `/api/feedback-comment/${comment.pk}/` return ax.delete(url) } export async function patchComment (comment: FeedbackComment): Promise<FeedbackComment> { const url = `/api/feedback-comment/${comment.pk}/` return (await ax.patch(url, comment)).data } export async function activateAllStudentAccess (): Promise<AxiosResponse<void>> { return ax.post('/api/student/activate/') } export async function deactivateAllStudentAccess (): Promise<AxiosResponse<void>> { return ax.post('/api/student/deactivate/') } export async function changePassword (userPk: string, data: {password: string}): Promise<UserAccount> { return (await ax.patch(`/api/user/${userPk}/change_password/`, data)).data } export async function getOwnUser (): Promise<UserAccount> { return (await ax.get('/api/user/me/')).data } export async function changeActiveForUser (userPk: string, active: boolean): Promise<UserAccount> { return (await ax.patch(`/api/user/${userPk}/change_active/`, { 'is_active': active })).data } export interface StudentExportOptions { setPasswords?: boolean } export interface StudentExportItem { Matrikel: string, Name: string, Username: string, Sum: number, Exam: string, Password: string, Scores: { type: string, score: number }[] } export async function fetchStudentExportData (options: StudentExportOptions): Promise<StudentExportItem[]> { return (await ax.post('/api/export/json/', options)).data } // Note, this interface does not represent all of the returned data, // but only the fields which have to be transformed for deanonymisation export interface InstanceExportData { students: { name: string, matrikelNo: string }[] } export async function fetchInstanceExportData (): Promise<InstanceExportData> { return (await ax.get('/api/instance/export')).data } ax.interceptors.response.use(undefined, errorInterceptor); export default ax