Use query param to store page index

This commit is contained in:
Daniel Egger 2023-05-09 07:56:38 +02:00
parent 089d41ee76
commit 7217424fdc
3 changed files with 82 additions and 35 deletions

View File

@ -14,6 +14,7 @@
"@sentry/vue": "^7.20.0",
"@urql/vue": "^1.0.2",
"@vueuse/core": "^9.13.0",
"@vueuse/router": "^10.1.2",
"cypress": "^12.9.0",
"d3": "^7.6.1",
"dayjs": "^1.11.7",
@ -25,7 +26,7 @@
"vue": "^3.2.38",
"vue-i18n": "^9.2.2",
"vue-i18n-extract": "^2.0.7",
"vue-router": "^4.1.5"
"vue-router": "^4.1.6"
},
"devDependencies": {
"@graphql-codegen/cli": "^2.13.12",
@ -7489,6 +7490,32 @@
"url": "https://github.com/sponsors/antfu"
}
},
"node_modules/@vueuse/router": {
"version": "10.1.2",
"resolved": "https://registry.npmjs.org/@vueuse/router/-/router-10.1.2.tgz",
"integrity": "sha512-99KhTBZliU5gRPHPhi7UO97vArgWIYLomLeCPYJQvbg1gYYa3BVX/uFDcdOaVYhdz5rWDeY/DaeW5CeNYR7zzQ==",
"dependencies": {
"@vueuse/shared": "10.1.2",
"vue-demi": ">=0.14.0"
},
"funding": {
"url": "https://github.com/sponsors/antfu"
},
"peerDependencies": {
"vue-router": ">=4.0.0-rc.1"
}
},
"node_modules/@vueuse/router/node_modules/@vueuse/shared": {
"version": "10.1.2",
"resolved": "https://registry.npmjs.org/@vueuse/shared/-/shared-10.1.2.tgz",
"integrity": "sha512-1uoUTPBlgyscK9v6ScGeVYDDzlPSFXBlxuK7SfrDGyUTBiznb3mNceqhwvZHjtDRELZEN79V5uWPTF1VDV8svA==",
"dependencies": {
"vue-demi": ">=0.14.0"
},
"funding": {
"url": "https://github.com/sponsors/antfu"
}
},
"node_modules/@vueuse/shared": {
"version": "9.13.0",
"resolved": "https://registry.npmjs.org/@vueuse/shared/-/shared-9.13.0.tgz",
@ -18979,9 +19006,9 @@
}
},
"node_modules/vue-demi": {
"version": "0.13.11",
"resolved": "https://registry.npmjs.org/vue-demi/-/vue-demi-0.13.11.tgz",
"integrity": "sha512-IR8HoEEGM65YY3ZJYAjMlKygDQn25D5ajNFNoKh9RSDMQtlzCxtfQjdQgv9jjK+m3377SsJXY8ysq8kLCZL25A==",
"version": "0.14.0",
"resolved": "https://registry.npmjs.org/vue-demi/-/vue-demi-0.14.0.tgz",
"integrity": "sha512-gt58r2ogsNQeVoQ3EhoUAvUsH9xviydl0dWJj7dabBC/2L4uBId7ujtCwDRD0JhkGsV1i0CtfLAeyYKBht9oWg==",
"hasInstallScript": true,
"bin": {
"vue-demi-fix": "bin/vue-demi-fix.js",
@ -25294,6 +25321,25 @@
"resolved": "https://registry.npmjs.org/@vueuse/metadata/-/metadata-9.13.0.tgz",
"integrity": "sha512-gdU7TKNAUVlXXLbaF+ZCfte8BjRJQWPCa2J55+7/h+yDtzw3vOoGQDRXzI6pyKyo6bXFT5/QoPE4hAknExjRLQ=="
},
"@vueuse/router": {
"version": "10.1.2",
"resolved": "https://registry.npmjs.org/@vueuse/router/-/router-10.1.2.tgz",
"integrity": "sha512-99KhTBZliU5gRPHPhi7UO97vArgWIYLomLeCPYJQvbg1gYYa3BVX/uFDcdOaVYhdz5rWDeY/DaeW5CeNYR7zzQ==",
"requires": {
"@vueuse/shared": "10.1.2",
"vue-demi": ">=0.14.0"
},
"dependencies": {
"@vueuse/shared": {
"version": "10.1.2",
"resolved": "https://registry.npmjs.org/@vueuse/shared/-/shared-10.1.2.tgz",
"integrity": "sha512-1uoUTPBlgyscK9v6ScGeVYDDzlPSFXBlxuK7SfrDGyUTBiznb3mNceqhwvZHjtDRELZEN79V5uWPTF1VDV8svA==",
"requires": {
"vue-demi": ">=0.14.0"
}
}
}
},
"@vueuse/shared": {
"version": "9.13.0",
"resolved": "https://registry.npmjs.org/@vueuse/shared/-/shared-9.13.0.tgz",
@ -33879,9 +33925,9 @@
}
},
"vue-demi": {
"version": "0.13.11",
"resolved": "https://registry.npmjs.org/vue-demi/-/vue-demi-0.13.11.tgz",
"integrity": "sha512-IR8HoEEGM65YY3ZJYAjMlKygDQn25D5ajNFNoKh9RSDMQtlzCxtfQjdQgv9jjK+m3377SsJXY8ysq8kLCZL25A=="
"version": "0.14.0",
"resolved": "https://registry.npmjs.org/vue-demi/-/vue-demi-0.14.0.tgz",
"integrity": "sha512-gt58r2ogsNQeVoQ3EhoUAvUsH9xviydl0dWJj7dabBC/2L4uBId7ujtCwDRD0JhkGsV1i0CtfLAeyYKBht9oWg=="
},
"vue-docgen-api": {
"version": "4.64.1",

View File

@ -25,6 +25,7 @@
"@sentry/vue": "^7.20.0",
"@urql/vue": "^1.0.2",
"@vueuse/core": "^9.13.0",
"@vueuse/router": "^10.1.2",
"cypress": "^12.9.0",
"d3": "^7.6.1",
"dayjs": "^1.11.7",
@ -36,7 +37,7 @@
"vue": "^3.2.38",
"vue-i18n": "^9.2.2",
"vue-i18n-extract": "^2.0.7",
"vue-router": "^4.1.5"
"vue-router": "^4.1.6"
},
"devDependencies": {
"@graphql-codegen/cli": "^2.13.12",

View File

@ -14,6 +14,7 @@ import type {
CourseSessionUser,
LearningContent,
} from "@/types";
import { useRouteQuery } from "@vueuse/router";
import dayjs from "dayjs";
import * as log from "loglevel";
import { computed, onMounted, reactive } from "vue";
@ -27,14 +28,11 @@ const userStore = useUserStore();
interface State {
assignment: Assignment | undefined;
courseSessionAssignmentDetails: CourseSessionAssignmentDetails | undefined;
pageIndex: number;
}
const state: State = reactive({
assignment: undefined,
courseSessionAssignmentDetails: undefined,
// 0 = introduction, 1 - n = tasks, n+1 = submission
pageIndex: 0,
});
const props = defineProps<{
@ -42,6 +40,9 @@ const props = defineProps<{
learningContent: LearningContent;
}>();
// 0 = introduction, 1 - n = tasks, n+1 = submission
const pageIndex = useRouteQuery("page", "0", { transform: Number, mode: "push" });
const assignmentCompletion = computed(() => assignmentStore.assignmentCompletion);
const completionStatus = computed(() => {
return assignmentCompletion.value?.completion_status ?? "in_progress";
@ -62,10 +63,11 @@ onMounted(async () => {
courseSessionId.value
);
if (completionStatus.value === "in_progress") {
state.pageIndex = 0;
} else {
state.pageIndex = numPages.value - 1;
if (
pageIndex.value === 0 &&
(completionStatus.value ?? "in_progress") !== "in_progress"
) {
pageIndex.value = numPages.value - 1;
}
} catch (error) {
log.error(error);
@ -74,9 +76,9 @@ onMounted(async () => {
const numTasks = computed(() => state.assignment?.tasks?.length ?? 0);
const numPages = computed(() => numTasks.value + 2);
const showPreviousButton = computed(() => state.pageIndex != 0);
const showNextButton = computed(() => state.pageIndex + 1 < numPages.value);
const showExitButton = computed(() => numPages.value === state.pageIndex + 1);
const showPreviousButton = computed(() => pageIndex.value != 0);
const showNextButton = computed(() => pageIndex.value + 1 < numPages.value);
const showExitButton = computed(() => numPages.value === pageIndex.value + 1);
const dueDate = computed(() =>
dayjs(state.courseSessionAssignmentDetails?.submissionDeadlineDateTimeUtc)
);
@ -84,41 +86,41 @@ const courseSessionId = computed(
() => courseSessionsStore.currentCourseSession?.id ?? 0
);
const currentTask = computed(() => {
if (state.pageIndex > 0 && state.pageIndex <= numTasks.value) {
return state.assignment?.tasks[state.pageIndex - 1];
if (pageIndex.value > 0 && pageIndex.value <= numTasks.value) {
return state.assignment?.tasks[pageIndex.value - 1];
}
return undefined;
});
const handleBack = () => {
log.debug("handleBack");
if (state.pageIndex > 0) {
state.pageIndex -= 1;
if (pageIndex.value > 0) {
pageIndex.value -= 1;
}
log.debug(`pageIndex: ${state.pageIndex}`);
log.debug(`pageIndex: ${pageIndex.value}`);
};
const handleContinue = () => {
log.debug("handleContinue");
if (state.pageIndex + 1 < numPages.value) {
state.pageIndex += 1;
if (pageIndex.value + 1 < numPages.value) {
pageIndex.value += 1;
}
log.debug(`pageIndex: ${state.pageIndex}`);
log.debug(`pageIndex: ${pageIndex.value}`);
};
const jumpToTask = (task: AssignmentTask) => {
log.debug("jumpToTask", task);
const index = state.assignment?.tasks.findIndex((t) => t.id === task.id);
if (index && index >= 0) {
state.pageIndex = index + 1;
pageIndex.value = index + 1;
}
log.debug(`pageIndex: ${state.pageIndex}`);
log.debug(`pageIndex: ${pageIndex.value}`);
};
const getTitle = () => {
if (0 === state.pageIndex) {
if (0 === pageIndex.value) {
return t("general.introduction");
} else if (state.pageIndex === numPages.value - 1) {
} else if (pageIndex.value === numPages.value - 1) {
return t("general.submission");
}
return currentTask?.value?.value.title ?? "Unknown";
@ -135,7 +137,7 @@ const assignmentUser = computed(() => {
<div v-if="state.assignment">
<div class="flex">
<LearningContentMultiLayout
:current-step="state.pageIndex"
:current-step="pageIndex"
:subtitle="state.assignment?.title ?? ''"
:title="getTitle()"
learning-content-type="assignment"
@ -153,7 +155,7 @@ const assignmentUser = computed(() => {
<div class="flex">
<div>
<AssignmentIntroductionView
v-if="state.pageIndex === 0 && state.assignment"
v-if="pageIndex === 0 && state.assignment"
:due-date="dueDate"
:assignment="state.assignment!"
></AssignmentIntroductionView>
@ -163,9 +165,7 @@ const assignmentUser = computed(() => {
:assignment-id="props.assignmentId"
></AssignmentTaskView>
<AssignmentSubmissionView
v-if="
state.pageIndex + 1 === numPages && state.assignment && courseSessionId
"
v-if="pageIndex + 1 === numPages && state.assignment && courseSessionId"
:due-date="dueDate"
:assignment="state.assignment!"
:assignment-completion-data="assignmentCompletion?.completion_data ?? {}"