Skip to content
Snippets Groups Projects
Commit 42bbbd7a authored by robinwilliam.hundt's avatar robinwilliam.hundt
Browse files

type safe student module

parent 623ff42d
No related branches found
No related tags found
1 merge request!119Typesafe store
......@@ -41,10 +41,10 @@
</template>
<script>
import { mapState } from 'vuex'
import {UI} from '@/store/modules/ui'
import BaseLayout from '@/components/BaseLayout'
import ExamInformation from '@/components/student/ExamInformation'
import { StudentPage } from '@/store/modules/student-page';
export default {
components: {BaseLayout, ExamInformation},
name: 'student-layout',
......@@ -60,14 +60,14 @@ export default {
}
},
computed: {
...mapState({
moduleReference: state => state.studentPage.exam.moduleReference,
submissions: state => state.studentPage.submissionsForList,
exam: state => state.studentPage.exam,
visited: state => state.studentPage.visited
}),
mini: function () { return UI.state.mini },
submissionNavItems: function () {
moduleReference () { return StudentPage.state.exam.moduleReference},
submissions () { return StudentPage.state.submissionsForList},
exam () { return StudentPage.state.exam},
visited () { return StudentPage.state.visited},
mini () { return UI.state.mini },
submissionNavItems () {
return this.submissions.map((sub, index) => {
return {
name: sub.type.name,
......
......@@ -16,6 +16,7 @@ import {mapState} from 'vuex'
import StudentLayout from './StudentLayout.vue'
import SubmissionList from '@/components/student/SubmissionList.vue'
import ExamInformation from '@/components/student/ExamInformation.vue'
import { StudentPage } from '@/store/modules/student-page';
export default {
components: {
......@@ -25,18 +26,16 @@ export default {
name: 'student-page',
created: function () {
if (!this.loaded) {
this.$store.dispatch('getStudentData').then(() => {
this.$store.dispatch('getStudentSubmissions')
StudentPage.getStudentData().then(() => {
StudentPage.getStudentSubmissions()
})
}
},
computed: {
...mapState({
studentName: state => state.studentPage.studentName,
exam: state => state.studentPage.exam,
submissions: state => state.studentPage.submissionsForList,
loaded: state => state.studentPage.loaded
})
studentName () { return StudentPage.state.studentName},
exam () { return StudentPage.state.exam},
submissions () { return StudentPage.state.submissionsForList},
loaded () { return StudentPage.state.loaded}
}
}
</script>
......
......@@ -59,7 +59,7 @@ import SubmissionType from '@/components/SubmissionType'
import BaseAnnotatedSubmission from '@/components/submission_notes/base/BaseAnnotatedSubmission'
import SubmissionLine from '@/components/submission_notes/base/SubmissionLine'
import FeedbackComment from '@/components/submission_notes/base/FeedbackComment'
import {studentPageMut} from '@/store/modules/student-page'
import {StudentPage} from '@/store/modules/student-page'
import {SubmissionNotes} from '@/store/modules/submission-notes'
import ToggleFeedbackVisibilityButton from '@/components/submission_notes/toolbars/ToggleFeedbackVisibilityButton'
import SubmissionTests from '@/components/SubmissionTests'
......@@ -81,19 +81,13 @@ export default {
return this.$route.params.id
},
submission () { return SubmissionNotes.submission },
...mapState({
submissionType (state) { return state.studentPage.submissionData[this.id].type },
feedback (state) {
return state.studentPage.submissionData[this.$route.params.id].feedback
},
showFeedback: function (state) {
return SubmissionNotes.state.ui.showFeedback
}
})
showFeedback: function (state) { return SubmissionNotes.state.ui.showFeedback },
submissionType () { return StudentPage.state.submissionData[this.id].type},
feedback () { return StudentPage.state.submissionData[this.$route.params.id].feedback}
},
methods: {
onRouteMountOrUpdate (routeId) {
this.$store.commit(studentPageMut.SET_VISITED, { index: routeId, visited: true })
StudentPage.SET_VISITED({ index: routeId, visited: true })
// TODO this seems fishy and there probably is the student page bug in here
SubmissionNotes.SET_SUBMISSION(this.$store.state.studentPage.submissionData[this.id])
}
......
......@@ -2,8 +2,9 @@ import {fetchStudentSelfData, fetchStudentSubmissions} from '@/api'
import {Exam, Submission, SubmissionList} from '@/models'
import {RootState} from '@/store/store'
import {Module} from 'vuex'
import { getStoreBuilder } from 'vuex-typex';
interface StudentPageState {
export interface StudentPageState {
studentName: string
exam?: Exam
submissionsForList: Array<SubmissionList>
......@@ -23,74 +24,73 @@ function initialState (): StudentPageState {
}
}
export const studentPageMut = Object.freeze({
SET_STUDENT_NAME: 'SET_STUDENT_NAME',
SET_EXAM: 'SET_EXAM',
SET_SUBMISSION_TYPES: 'SET_SUBMISSION_TYPES',
SET_SUBMISSIONS_FOR_LIST: 'SET_SUBMISSIONS_FOR_LIST',
SET_FULL_SUBMISSION_DATA: 'SET_FULL_SUBMISSION_DATA',
SET_VISITED: 'SET_VISITED',
SET_LOADED: 'SET_LOADED',
RESET_STATE: 'RESET_STATE'
})
const mb = getStoreBuilder<RootState>().module('SutdenPage', initialState())
const studentPage: Module<StudentPageState, RootState> = {
state: initialState(),
mutations: {
[studentPageMut.SET_STUDENT_NAME] (state, name) {
state.studentName = name
},
[studentPageMut.SET_EXAM] (state, exam) {
state.exam = exam
},
[studentPageMut.SET_SUBMISSIONS_FOR_LIST] (state, submissions) {
state.submissionsForList = submissions
},
/**
* Reduces the array submissionData returned by the /api/student-submissions
* into an object where the keys are the SubmissionType id's and the values
* the former array elements. This is done to have direct access to the data
* via the SubmissionType id.
*/
[studentPageMut.SET_FULL_SUBMISSION_DATA] (state, submissionData: Array<Submission>) {
state.submissionData = submissionData.reduce((acc: {[pk: string]: Submission}, cur) => {
acc[cur.type.pk] = cur
return acc
}, {})
},
[studentPageMut.SET_VISITED] (state, visited) {
state.visited = { ...state.visited, [visited.index]: visited.visited }
},
[studentPageMut.SET_LOADED] (state, loaded) {
state.loaded = loaded
},
[studentPageMut.RESET_STATE] (state) {
Object.assign(state, initialState())
}
},
actions: {
const stateGetter = mb.state()
async getStudentData (context) {
try {
const studentData = await fetchStudentSelfData()
context.commit(studentPageMut.SET_STUDENT_NAME, studentData.name)
context.commit(studentPageMut.SET_EXAM, studentData.exam)
context.commit(studentPageMut.SET_SUBMISSIONS_FOR_LIST, studentData.submissions)
context.commit(studentPageMut.SET_LOADED, true)
} catch (e) {
console.log(e)
}
},
function SET_STUDENT_NAME (state: StudentPageState, name: string) {
state.studentName = name
}
function SET_EXAM (state: StudentPageState, exam: Exam) {
state.exam = exam
}
function SET_SUBMISSIONS_FOR_LIST (state: StudentPageState, submissions: SubmissionList[]) {
state.submissionsForList = submissions
}
/**
* Reduces the array submissionData returned by the /api/student-submissions
* into an object where the keys are the SubmissionType id's and the values
* the former array elements. This is done to have direct access to the data
* via the SubmissionType id.
*/
function SET_FULL_SUBMISSION_DATA (state: StudentPageState, submissionData: Array<Submission>) {
state.submissionData = submissionData.reduce((acc: {[pk: string]: Submission}, cur) => {
acc[cur.type.pk] = cur
return acc
}, {})
}
function SET_VISITED (state: StudentPageState, visited: {index: string, visited: boolean}) {
state.visited = { ...state.visited, [visited.index]: visited.visited }
}
function SET_LOADED (state: StudentPageState, loaded: boolean) {
state.loaded = loaded
}
function RESET_STATE (state: StudentPageState) {
Object.assign(state, initialState())
}
async getStudentSubmissions (context) {
try {
const submissions = await fetchStudentSubmissions()
context.commit(studentPageMut.SET_FULL_SUBMISSION_DATA, submissions)
} catch (e) {
console.log(e)
}
}
async function getStudentData () {
try {
const studentData = await fetchStudentSelfData()
StudentPage.SET_STUDENT_NAME(studentData.name || '')
StudentPage.SET_EXAM(studentData.exam)
StudentPage.SET_SUBMISSIONS_FOR_LIST(studentData.submissions)
StudentPage.SET_LOADED(true)
} catch (e) {
console.log(e)
}
}
export default studentPage
async function getStudentSubmissions () {
try {
const submissions = await fetchStudentSubmissions()
StudentPage.SET_FULL_SUBMISSION_DATA(submissions)
} catch (e) {
console.log(e)
}
}
export const StudentPage = {
get state () { return stateGetter() },
SET_STUDENT_NAME: mb.commit(SET_STUDENT_NAME),
SET_EXAM: mb.commit(SET_EXAM),
SET_SUBMISSIONS_FOR_LIST: mb.commit(SET_SUBMISSIONS_FOR_LIST),
SET_FULL_SUBMISSION_DATA: mb.commit(SET_FULL_SUBMISSION_DATA),
SET_VISITED: mb.commit(SET_VISITED),
SET_LOADED: mb.commit(SET_LOADED),
RESET_STATE: mb.commit(RESET_STATE),
getStudentData: mb.dispatch(getStudentData),
getStudentSubmissions: mb.dispatch(getStudentSubmissions)
}
......@@ -3,7 +3,6 @@ import Vue from 'vue'
import createPersistedState from 'vuex-persistedstate'
import {getStoreBuilder} from 'vuex-typex'
import studentPage from './modules/student-page'
import './modules/ui'
import './modules/authentication'
......@@ -11,6 +10,7 @@ import './modules/feedback_list/feedback-search-options'
import './modules/feedback_list/feedback-table'
import './modules/subscriptions'
import './modules/submission-notes'
import './modules/student-page'
import './mutations'
import './actions'
......@@ -19,10 +19,11 @@ import './getters'
import {UIState} from './modules/ui'
import {AuthState} from './modules/authentication'
import {FeedbackSearchOptionsState, FeedbackSearchOptions} from './modules/feedback_list/feedback-search-options'
import {Subscriptions, SubscriptionsState} from './modules/subscriptions'
import {FeedbackTableState, FeedbackTable} from './modules/feedback_list/feedback-table'
import { SubmissionNotesState } from './modules/submission-notes'
import {FeedbackSearchOptionsState} from './modules/feedback_list/feedback-search-options'
import {SubscriptionsState} from './modules/subscriptions'
import {FeedbackTableState} from './modules/feedback_list/feedback-table'
import {SubmissionNotesState} from './modules/submission-notes'
import {StudentPageState} from './modules/student-page'
import {lastInteraction} from '@/store/plugins/lastInteractionPlugin'
import {
......@@ -53,7 +54,8 @@ export interface RootState extends RootInitialState{
FeedbackSearchOptions: FeedbackSearchOptionsState,
FeedbackTable: FeedbackTableState,
Subscriptions: SubscriptionsState,
SubmissionNotes: SubmissionNotesState
SubmissionNotes: SubmissionNotesState,
StudentPage: StudentPageState
}
export function initialState (): RootInitialState {
......@@ -79,9 +81,6 @@ export const persistedStateKey = 'grady'
const store = getStoreBuilder<RootState>().vuexStore({
strict: process.env.NODE_ENV === 'development',
modules: {
studentPage
},
plugins: [
createPersistedState({
key: persistedStateKey,
......@@ -89,7 +88,7 @@ const store = getStoreBuilder<RootState>().vuexStore({
// Authentication.token is manually saved since using it with this plugin caused issues
// when manually reloading the page
paths: Object.keys(initialState()).concat(
['UI', 'studentPage', 'submissionNotes', 'FeedbackSearchOptions', 'Subscriptions',
['UI', 'StudentPage', 'SubmissionNotes', 'FeedbackSearchOptions', 'Subscriptions',
'Authentication.user', 'Authentication.jwtTimeDelta',
'Authentication.tokenCreationTime'])
}),
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment