Skip to content

Commit

Permalink
Scan Navigation (#613)
Browse files Browse the repository at this point in the history
* Route views by scan, not frame

* Add ProjectComplete page to act as transition between projects
  • Loading branch information
annehaley authored Oct 11, 2022
1 parent a7faa51 commit d5be52e
Show file tree
Hide file tree
Showing 6 changed files with 153 additions and 64 deletions.
19 changes: 10 additions & 9 deletions web_client/src/components/ControlPanel.vue
Original file line number Diff line number Diff line change
Expand Up @@ -92,6 +92,7 @@ export default {
...mapMutations([
'setShowCrosshairs',
'setStoreCrosshairs',
'setCurrentFrameId',
]),
openScanLink() {
window.open(this.currentViewData.scanLink, '_blank');
Expand Down Expand Up @@ -125,25 +126,26 @@ export default {
}
}
},
navigateToFrame(frameId) {
if (frameId && frameId !== this.$route.params.frameId) {
navigateToScan(location) {
if (!location) location = 'complete';
if (location && location !== this.$route.params.scanId) {
this.$router
.push(`/${this.currentViewData.projectId}/${frameId}` || '')
.push(`/${this.currentViewData.projectId}/${location}` || '')
.catch(this.handleNavigationError);
}
},
slideToFrame(framePosition) {
this.navigateToFrame(this.currentViewData.scanFramesList[framePosition - 1]);
this.setCurrentFrameId(this.currentViewData.scanFramesList[framePosition - 1]);
},
updateImage() {
if (this.direction === 'back') {
this.navigateToFrame(this.previousFrame);
this.setCurrentFrameId(this.previousFrame);
} else if (this.direction === 'forward') {
this.navigateToFrame(this.nextFrame);
this.setCurrentFrameId(this.nextFrame);
} else if (this.direction === 'previous') {
this.navigateToFrame(this.currentViewData.upTo);
this.navigateToScan(this.currentViewData.upTo);
} else if (this.direction === 'next') {
this.navigateToFrame(this.currentViewData.downTo);
this.navigateToScan(this.currentViewData.downTo);
}
},
handleKeyPress(direction) {
Expand Down Expand Up @@ -355,7 +357,6 @@ export default {
<v-icon>fa-caret-up</v-icon>
</v-btn>
<v-btn
:disabled="!currentViewData.downTo"
small
depressed
class="transparent-btn"
Expand Down
8 changes: 4 additions & 4 deletions web_client/src/components/ExperimentsView.vue
Original file line number Diff line number Diff line change
Expand Up @@ -96,8 +96,8 @@ export default {
}
return str;
},
getURLForFirstFrameInScan(scanId) {
return `/${this.currentProject.id}/${this.scanFrames[scanId][0]}`;
getURLForScan(scanId) {
return `/${this.currentProject.id}/${scanId}`;
},
decisionToRating(decisions) {
if (decisions.length === 0) return {};
Expand Down Expand Up @@ -205,7 +205,7 @@ export default {
>
<span>All scans</span>
<v-switch
:input-value="true"
:input-value="reviewMode"
dense
style="display: inline-block; max-height: 40px; max-width: 60px;"
class="px-3 ma-0"
Expand Down Expand Up @@ -304,7 +304,7 @@ export default {
<template #activator="{ on, attrs }">
<v-btn
v-bind="attrs"
:to="getURLForFirstFrameInScan(scan.id)"
:to="getURLForScan(scan.id)"
:disabled="!includeScan(scan.id)"
class="ml-0 px-1 scan-name"
href
Expand Down
13 changes: 9 additions & 4 deletions web_client/src/router.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import Vue from 'vue';
import Router from 'vue-router';

import Projects from './views/Projects.vue';
import Frame from './views/Frame.vue';
import Scan from './views/Scan.vue';

Vue.use(Router);

Expand All @@ -15,9 +15,14 @@ export default new Router({
},
// Order matters
{
path: '/:projectId?/:frameId?',
name: 'frame',
component: Frame,
path: '/:projectId?/complete',
name: 'projectComplete',
component: Projects,
},
{
path: '/:projectId?/:scanId?',
name: 'scan',
component: Scan,
},
{
path: '*',
Expand Down
17 changes: 6 additions & 11 deletions web_client/src/store/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -387,10 +387,8 @@ const {
scanFramesList,
scanPosition: experimentScansList.indexOf(scan.id) + 1,
framePosition: scanFramesList.indexOf(currentFrame.id) + 1,
backTo: currentFrame.previousFrame,
forwardTo: currentFrame.nextFrame,
upTo: state.scanFrames[upTo] ? state.scanFrames[upTo][0] : undefined,
downTo: state.scanFrames[downTo] ? state.scanFrames[downTo][0] : undefined,
upTo,
downTo,
currentFrame,
currentAutoEvaluation: currentFrame.frame_evaluation,
};
Expand Down Expand Up @@ -731,16 +729,16 @@ const {
},
});
},
async getFrame({ state, dispatch }, { frameId, projectId }) {
if (!frameId) {
async getScan({ state, dispatch }, { scanId, projectId }) {
if (!scanId) {
return undefined;
}
if (!state.frames[frameId]) {
if (!state.scans[scanId]) {
await dispatch('loadProjects');
const targetProject = state.projects.filter((proj) => proj.id === projectId)[0];
await dispatch('loadProject', targetProject);
}
return state.frames[frameId];
return state.scans[scanId];
},
async setCurrentFrame({ commit }, frameId) {
commit('setCurrentFrameId', frameId);
Expand All @@ -751,9 +749,6 @@ const {
if (!frame) {
throw new Error("frame id doesn't exist");
}
if (getters.currentFrame === frame) {
return;
}
commit('setLoadingFrame', true);
commit('setErrorLoadingFrame', false);
const oldScan = getters.currentScan;
Expand Down
98 changes: 92 additions & 6 deletions web_client/src/views/Projects.vue
Original file line number Diff line number Diff line change
Expand Up @@ -26,20 +26,20 @@ export default defineComponent({
},
inject: ['user', 'MIQAConfig'],
setup() {
const { switchReviewMode } = store.commit;
const loadingProjects = ref(true);
store.dispatch.loadProjects().then(() => {
loadingProjects.value = false;
});
const reviewMode = computed(() => store.state.reviewMode);
const complete = window.location.hash.includes('complete');
const currentProject = computed(() => store.state.currentProject);
const currentTaskOverview = computed(() => store.state.currentTaskOverview);
const projects = computed(() => store.state.projects);
const isGlobal = computed(() => store.getters.isGlobal);
const selectedProjectIndex = ref(projects.value.findIndex(
(project) => project.id === currentProject.value?.id,
));
const selectProject = (project: Project) => {
store.dispatch.loadProject(project);
};
const selectGlobal = () => {
store.dispatch.loadGlobal();
};
Expand Down Expand Up @@ -88,29 +88,51 @@ export default defineComponent({
);
}
async function getProjectFromURL() {
if (complete) {
const targetProjectIndex = projects.value.findIndex(
(project) => project.id === window.location.hash.split('/')[1],
);
const targetProject = projects.value[targetProjectIndex];
if (targetProject) store.commit.setCurrentProject(targetProject);
selectedProjectIndex.value = targetProjectIndex;
}
}
const overviewPoll = setInterval(refreshTaskOverview, 10000);
watch(currentTaskOverview, setOverviewSections);
watch(currentProject, refreshTaskOverview);
watch(projects, getProjectFromURL);
return {
reviewMode,
switchReviewMode,
complete,
currentProject,
loadingProjects,
currentTaskOverview,
selectedProjectIndex,
projects,
isGlobal,
overviewPoll,
selectProject,
selectGlobal,
overviewSections,
setOverviewSections,
refreshAllTaskOverviews,
getProjectFromURL,
};
},
data: () => ({
creating: false,
newName: '',
}),
watch: {
projects() {
this.$nextTick(() => {
if (this.$refs.proceed) this.$refs.proceed.$el.focus();
});
},
},
mounted() {
this.setOverviewSections();
window.addEventListener('keydown', (event) => {
Expand All @@ -130,6 +152,12 @@ export default defineComponent({
},
methods: {
...mapMutations(['setProjects', 'setCurrentProject']),
selectProject(project: Project) {
if (this.complete) {
this.complete = false;
}
store.dispatch.loadProject(project);
},
async createProject() {
if (this.creating && this.newName.length > 0) {
try {
Expand All @@ -150,6 +178,26 @@ export default defineComponent({
}
}
},
async proceedToNext() {
const nextProject = this.projects[this.selectedProjectIndex + 1];
store.dispatch.loadProject(nextProject);
this.selectedProjectIndex += 1;
await djangoRest.projectTaskOverview(nextProject.id).then(
(taskOverview) => {
let nextScanIndex = 0;
let nextScan;
let nextScanState;
while (
!nextScan || (nextScanState === 'complete' && this.reviewMode)
) {
nextScan = nextProject.experiments[0].scans[nextScanIndex];
nextScanState = taskOverview.scan_states[nextScan.id];
nextScanIndex += 1;
}
this.$router.push(`/${nextProject.id}/${nextScan.id}` || '');
},
);
},
},
});
</script>
Expand Down Expand Up @@ -240,7 +288,7 @@ export default defineComponent({
</v-navigation-drawer>
</v-card>
<div
v-if="currentProject !== undefined"
v-if="currentProject !== undefined && !complete"
class="flex-grow-1 ma-3 pa-5"
>
<v-card-title v-if="isGlobal">
Expand Down Expand Up @@ -304,7 +352,41 @@ export default defineComponent({
fill-height
>
<div
v-if="projects.length > 0"
v-if="complete"
class="title text-center"
>
Viewed all scans in Project {{ currentProject.name }}.
<div
v-if="selectedProjectIndex + 1 < projects.length"
>
Proceed to next Project, {{ projects[selectedProjectIndex+1].name }}?
<br>
<v-form @submit.prevent="proceedToNext">
<v-btn
ref="proceed"
class="my-3"
type="submit"
>
Proceed
</v-btn>
</v-form>
</div>
<v-subheader
class="mode-toggle"
>
<span>All scans</span>
<v-switch
:input-value="reviewMode"
dense
style="display: inline-block; max-height: 40px; max-width: 60px;"
class="px-3 ma-0"
@change="switchReviewMode"
/>
<span>Scans for my review</span>
</v-subheader>
</div>
<div
v-else-if="projects.length > 0"
class="title"
>
Select a project
Expand Down Expand Up @@ -348,4 +430,8 @@ export default defineComponent({
width: 100%;
text-align: center;
}
.mode-toggle {
align-items: baseline;
display: inline-block;
}
</style>
Loading

0 comments on commit d5be52e

Please sign in to comment.