Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions app/core/message_exception.py
Original file line number Diff line number Diff line change
Expand Up @@ -88,7 +88,7 @@ def __init__(
title: str = "Permission Denied",
msg: str = "You do not have permission to access the requested content",
):
super().__init__(title, msg, MsgSeverity.WARN, False, 401)
super().__init__(title, msg, MsgSeverity.WARN, False, 403)


class MsgFailure(MsgException):
Expand Down Expand Up @@ -125,5 +125,5 @@ class MsgBuilder:
# title: str = "Share Not Allowed",
# msg: str = "Students cannot be added as collaborator to widgets that have guest access disabled",
# ) -> Msg:
# return Msg(title, msg, MsgType.STUDENT_COLLAB, MsgSeverity.ERROR, False, 401)
# return Msg(title, msg, MsgType.STUDENT_COLLAB, MsgSeverity.ERROR, False, 403)
pass
10 changes: 2 additions & 8 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -24,19 +24,19 @@
},
"dependencies": {
"@mdx-js/loader": "^3.1.0",
"@tanstack/react-query": "^5.96.2",
"d3": "^7.2.0",
"fs-extra": "^8.0.1",
"js-base64": "^3.7.2",
"react-datepicker": "^5.0.0",
"react-overlays": "^5.2.1",
"react-query": "^3.39.3",
"uuid": "^9.0.1"
},
"devDependencies": {
"@babel/core": "^7.10.4",
"@babel/preset-env": "^7.10.4",
"@babel/preset-react": "^7.10.4",
"@cfaester/enzyme-adapter-react-18": "^0.8.0",
"@cfaester/enzyme-adapter-react-18": "^0.8.0",
"@testing-library/dom": "^10.4.0",
"@testing-library/jest-dom": "^6.6.3",
"@testing-library/react": "^16.2.0",
Expand All @@ -49,7 +49,6 @@
"css-loader": "^6.7.3",
"enzyme": "^3.11.0",
"enzyme-to-json": "^3.6.2",
"husky": "^4.2.5",
"jest": "^29.3.1",
"jest-environment-jsdom": "^29.4.3",
"jquery": "3.5.1",
Expand Down Expand Up @@ -88,11 +87,6 @@
"yarn prettier --write"
]
},
"husky": {
"hooks": {
"pre-commit": "yarn test:ci && yarn lint-staged"
}
},
"browserslist": [
"> 0.5%",
"not ie >= 0",
Expand Down
2 changes: 1 addition & 1 deletion src/404.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import React from 'react'
import {createRoot} from 'react-dom/client'
import { QueryClient, QueryClientProvider, QueryCache } from 'react-query'
import { QueryClient, QueryClientProvider, QueryCache } from '@tanstack/react-query'
import Action404 from './components/404'

const queryCache = new QueryCache()
Expand Down
2 changes: 1 addition & 1 deletion src/500.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import React from 'react'
import {createRoot} from 'react-dom/client'
import { QueryClient, QueryClientProvider, QueryCache } from 'react-query'
import { QueryClient, QueryClientProvider, QueryCache } from '@tanstack/react-query'
import Action500 from './components/500'

const queryCache = new QueryCache()
Expand Down
2 changes: 1 addition & 1 deletion src/catalog.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import React from 'react'
import {createRoot} from 'react-dom/client'
import { QueryClient, QueryClientProvider, QueryCache } from 'react-query'
import { QueryClient, QueryClientProvider, QueryCache } from '@tanstack/react-query'
import CatalogPage from './components/catalog-page'

const queryCache = new QueryCache()
Expand Down
2 changes: 1 addition & 1 deletion src/closed.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import React from 'react'
import {createRoot} from 'react-dom/client'
import { QueryClient, QueryClientProvider, QueryCache } from 'react-query'
import { QueryClient, QueryClientProvider, QueryCache } from '@tanstack/react-query'
import Closed from './components/closed'

const queryCache = new QueryCache()
Expand Down
6 changes: 3 additions & 3 deletions src/components/catalog-page.jsx
Original file line number Diff line number Diff line change
@@ -1,13 +1,13 @@
import React from 'react'
import { useQuery } from 'react-query'
import { useQuery } from '@tanstack/react-query'
import { apiGetWidget } from '@/util/api'
import Header from './header'
import Catalog from './catalog'

const CatalogPage = () => {
const { data: widgets, isLoading} = useQuery({
queryKey: 'catalog-widgets',
queryFn: () => apiGetWidget([], 'catalog'),
queryKey: ['catalog-widgets'],
queryFn: () => apiGetWidget(),
staleTime: Infinity
})

Expand Down
4 changes: 2 additions & 2 deletions src/components/detail-page.jsx
Original file line number Diff line number Diff line change
@@ -1,15 +1,15 @@
import React from 'react'
import Header from './header'
import Detail from './detail'
import { useQuery } from 'react-query'
import { useQuery } from '@tanstack/react-query'
import { apiGetWidget } from '../util/api'
import LoadingIcon from './loading-icon'

const DetailPage = () => {
const nameArr = window.location.pathname.replace('/widgets/', '').replace(/\/$/, "").split('/')
const widgetID = nameArr.pop().split('-').shift()
const { data: widget, isFetching: isFetching} = useQuery({
queryKey: 'widget',
queryKey: ['widget'],
queryFn: () => apiGetWidget(widgetID),
enabled: !!widgetID,
placeholderData: {},
Expand Down
53 changes: 27 additions & 26 deletions src/components/extra-attempts-dialog.jsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import React, { useEffect, useState, useRef, useMemo } from 'react'
import { useQuery } from 'react-query'
import { useQuery } from '@tanstack/react-query'
import { apiGetExtraAttempts, apiGetUsers } from '../util/api'
import { useCreateExtraAttempts, useDeleteExtraAttempts, useUpdateExtraAttempts } from './hooks/useExtraAttempts'
import Modal from './modal'
Expand Down Expand Up @@ -34,51 +34,52 @@ const ExtraAttemptsDialog = ({onClose, inst}) => {
const createExtraAttempts = useCreateExtraAttempts()
const deleteExtraAttempts = useDeleteExtraAttempts()
const updateExtraAttempts = useUpdateExtraAttempts()
const { data: attempts, isLoading: attemptsLoading, isFetching, remove: removeAttempts } = useQuery({
queryKey: 'extra-attempts',
const { data: attempts, isLoading: attemptsLoading, isFetching, remove: removeAttempts, error: attemptsError } = useQuery({
queryKey: ['extra-attempts'],
queryFn: () => apiGetExtraAttempts(inst.id),
placeholderData: [],
staleTime: Infinity,
onError: (err) => {
if (err.message == "Invalid Login") {
window.location.href = '/login'
} else {
setError((err.message || "Error") + ": Failed to retrieve extra attempts.")
}
}
staleTime: Infinity
})
const { data: queryUsers, remove: removeUsers } = useQuery({
const { data: queryUsers, remove: removeUsers, error: usersError } = useQuery({
queryKey: ['attempt-users', inst.id],
queryFn: () => apiGetUsers(state.userIDs),
enabled: !!state.userIDs && state.userIDs.length > 0 && attemptsLoading == false,
placeholderData: {},
staleTime: Infinity,
onError: (err) => {
if (err.message == "Invalid Login") {
window.location.href = '/login'
} else {
setError((err.message || "Error") + ": Failed to retrieve user(s).")
}
}
staleTime: Infinity
})

useEffect(() => {
mounted.current = true
return () => (mounted.current = false)
[usersError, attemptsError].some((someErr) => {
switch (someErr.status) {
case 401:
window.location.href = '/login'
break
default:
if (someErr == usersError)
setError((err.message || "Error") + ": Failed to retrieve user(s).")
else if (someErr == attemptsError)
setError((err.message || "Error") + ": Failed to retrieve extra attempts.")
}
})
}, [usersError, attemptsError])

useEffect(() => {
mounted.current = true
return () => (mounted.current = false)
}, [])

// Sets the users and attempts on load
useEffect(() => {
if (attempts !== null && mounted.current) {
const idArr = []
attempts.forEach(user => {idArr.push(user.user)})
setState({...state, userIDs: idArr, extraAttempts: attempts})
attempts.forEach(user => {idArr.push(user.user) })
setState({...state, userIDs: idArr, extraAttempts: attempts })
}
}, [JSON.stringify(attempts), mounted.current])

useEffect(() => {
if (mounted.current) {
setState({...state, users: {...queryUsers}})
setState({...state, users: {...queryUsers }})
}
}, [JSON.stringify(queryUsers)])

Expand All @@ -87,7 +88,7 @@ const ExtraAttemptsDialog = ({onClose, inst}) => {
const tempUsers = {...state.users}
const tempAttempts = [...state.extraAttempts]

if(!(match.id in state.users)){
if ( !(match.id in state.users)){
tempUsers[match.id] = match

// add another extra attempts row if needed
Expand Down
4 changes: 2 additions & 2 deletions src/components/header.jsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import React, { useState, useEffect } from 'react'
import { useQuery } from 'react-query'
import { useQuery } from '@tanstack/react-query'
import { apiGetUser, apiUserVerify } from '../util/api'
import Notifications from './notifications'

Expand All @@ -14,7 +14,7 @@ const Header = ({
const [permLevel, setPermLevel] = useState('anonymous')

const { data: userPerms } = useQuery({
queryKey: 'isLoggedIn',
queryKey: ['isLoggedIn'],
queryFn: apiUserVerify,
staleTime: Infinity,
retry: false
Expand Down
29 changes: 12 additions & 17 deletions src/components/hooks/useCopyWidget.jsx
Original file line number Diff line number Diff line change
@@ -1,37 +1,32 @@
import { useMutation, useQueryClient } from 'react-query'
import { useMutation, useQueryClient } from '@tanstack/react-query'
import { apiCopyWidget } from '../../util/api'

/**
* It optimistically updates the cache value on mutate
* @returns The mutation function and the result of the mutation
*/
export default function useCopyWidget(user) {
const queryClient = useQueryClient()

// Optimistically updates the cache value on mutate
return useMutation(
apiCopyWidget,
{
mutationFn: apiCopyWidget,
onSuccess: (data, variables) => {
if (queryClient.getQueryData(['instances', user]))
{
// optimistically update the query cache with the new instance info
queryClient.setQueryData(['instances', user], (previous) => ({
// update the query cache with the new instance info
queryClient.setQueryData(['instances', user], (previous) => {
if (!previous || !previous.pages) return previous
return {
...previous,
pages: previous.pages.map((page, index) => {
if (index == 0) return { ...page, results: [ data, ...page.results] }
if (index == 0) return { ...page, results: [data, ...page.results] }
else return page
}),
modified: Math.floor(Date.now() / 1000)
}))
}
}
})

variables.successFunc(data)

queryClient.invalidateQueries({ queryKey: ['instances', user] })
},
onError: (err, variables, context) => {
variables.errorFunc(err)
queryClient.setQueryData(['instances', user], (previous) => {
return context.previousValue
})
}
}
)
Expand Down
4 changes: 2 additions & 2 deletions src/components/hooks/useCreatePlaySession.jsx
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
import { useMutation } from 'react-query'
import { useMutation } from '@tanstack/react-query'
import { apiCreatePlaySession } from '../../util/api'


export default function useCreatePlaySession() {
return useMutation(
apiCreatePlaySession,
{
mutationFn: apiCreatePlaySession,
onSuccess: (data, variables) => {
variables.successFunc(data)
},
Expand Down
32 changes: 17 additions & 15 deletions src/components/hooks/useDeleteNotification.jsx
Original file line number Diff line number Diff line change
@@ -1,37 +1,39 @@
import { useMutation, useQueryClient } from 'react-query'
import { useMutation, useQueryClient } from '@tanstack/react-query'
import { apiDeleteNotification } from '../../util/api'

export default function useDeleteNotification() {
const queryClient = useQueryClient()

return useMutation(
apiDeleteNotification,
{
// Handles the optomistic update for deleting a Notification
mutationFn: apiDeleteNotification,
// Handles the optimistic update for deleting a Notification
onMutate: async data => {
await queryClient.cancelQueries('notifications')
// Cancel queries that update notification data
await queryClient.cancelQueries({ queryKey: ['notifications'] })

const previousValue = queryClient.getQueryData('notifications')
// Hold the current notification data
const previousValue = queryClient.getQueryData(['notifications'])

if (data.deleteAll)
{
queryClient.setQueryData('notifications', [])
// Set it to the expected value
if (data.deleteAll) {
queryClient.setQueryData(['notifications'], [])
}
else
{
queryClient.setQueryData('notifications', old => old.filter(notif => notif.id != data.notifId))
else {
queryClient.setQueryData(['notifications'], old => old.filter(notif => notif.id != data.notifId))
}

// Stores the old value for use if there is an error
// Return the data if there is an update
return { previousValue }
},
onSuccess: (data, variables) => {
// queryClient.invalidateQueries('notifications')
if (data) variables.successFunc(data);
// Invalidate the queries. What if we didn't correctly predict output?
queryClient.invalidateQueries({ queryKey: ['notifications'] })
variables.successFunc(data);
},
onError: (err, variables, context) => {
variables.errorFunc(err)
queryClient.setQueryData('notifications', context.previousValue)
queryClient.setQueryData(['notifications'], context.previousValue)
}
}
)
Expand Down
Loading
Loading