Skip to content

Commit

Permalink
Merge pull request jplag#1320 from jplag/report-viewer/view-wrapper
Browse files Browse the repository at this point in the history
Wrapper for async Views
  • Loading branch information
sebinside authored Sep 29, 2023
2 parents 94301a0 + 953bdc9 commit 9149f42
Show file tree
Hide file tree
Showing 12 changed files with 219 additions and 59 deletions.
4 changes: 1 addition & 3 deletions report-viewer/src/App.vue
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,7 @@
<div
class="max-w-screen max-h-fit min-h-screen bg-backgorund-light text-black dark:bg-backgorund-dark dark:text-amber-50"
>
<Suspense>
<RouterView class="max-h-screen overflow-hidden" />
</Suspense>
<RouterView class="max-h-screen overflow-hidden" />

<Button
class="absolute bottom-2 right-2 flex h-12 w-12 items-center justify-center text-center"
Expand Down
18 changes: 18 additions & 0 deletions report-viewer/src/components/LoadingCircle.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
<template>
<div>
<div
class="mx-auto h-16 w-16 animate-spin rounded-full border-8 border-interactable-border-light border-t-accent dark:border-interactable-border-dark dark:border-t-accent"
></div>
<p class="text-2xl font-bold">{{ message }}</p>
</div>
</template>

<script setup lang="ts">
defineProps({
message: {
type: String,
required: false,
default: 'Loading Files...'
}
})
</script>
16 changes: 8 additions & 8 deletions report-viewer/src/router/index.ts
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
import { createRouter, createWebHistory } from 'vue-router'
import FileUploadView from '@/views/FileUploadView.vue'
import OverviewView from '@/views/OverviewView.vue'
import ComparisonView from '@/views/ComparisonView.vue'
import OverviewViewWrapper from '@/viewWrapper/OverviewViewWrapper.vue'
import ComparisonViewWrapper from '@/viewWrapper/ComparisonViewWrapper.vue'
import ErrorView from '@/views/ErrorView.vue'
import ClusterView from '@/views/ClusterView.vue'
import InformationView from '@/views/InformationView.vue'
import InformationViewWrapper from '@/viewWrapper/InformationViewWrapper.vue'
import ClusterViewWrapper from '@/viewWrapper/ClusterViewWrapper.vue'

/**
* The router is used to navigate between the different views of the application.
Expand All @@ -20,12 +20,12 @@ const router = createRouter({
{
path: '/overview',
name: 'OverviewView',
component: OverviewView
component: OverviewViewWrapper
},
{
path: '/comparison/:firstId/:secondId',
name: 'ComparisonView',
component: ComparisonView,
component: ComparisonViewWrapper,
props: true
},
{
Expand All @@ -36,13 +36,13 @@ const router = createRouter({
{
path: '/cluster/:clusterIndex',
name: 'ClusterView',
component: ClusterView,
component: ClusterViewWrapper,
props: true
},
{
path: '/info',
name: 'InfoView',
component: InformationView
component: InformationViewWrapper
}
]
})
Expand Down
32 changes: 32 additions & 0 deletions report-viewer/src/viewWrapper/ClusterViewWrapper.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
<template>
<ClusterView v-if="overview" :overview="overview" :cluster="overview.clusters[clusterIndex]" />
<div
v-else
class="absolute bottom-0 left-0 right-0 top-0 flex flex-col items-center justify-center"
>
<LoadingCircle class="mx-auto" />
</div>
</template>

<script setup lang="ts">
import { type Ref, ref, computed } from 'vue'
import { OverviewFactory } from '@/model/factories/OverviewFactory'
import ClusterView from '@/views/ClusterView.vue'
import LoadingCircle from '@/components/LoadingCircle.vue'
import type { Overview } from '@/model/Overview'
const props = defineProps({
clusterIndex: {
type: String,
required: true
}
})
const clusterIndex = computed(() => parseInt(props.clusterIndex))
const overview: Ref<Overview | null> = ref(null)
OverviewFactory.getOverview().then((o) => {
overview.value = o
})
</script>
49 changes: 49 additions & 0 deletions report-viewer/src/viewWrapper/ComparisonViewWrapper.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
<template>
<ComparisonView
v-if="comparison && language"
:first-id="firstId"
:second-id="secondId"
:comparison="comparison"
:language="language"
/>
<div
v-else
class="absolute bottom-0 left-0 right-0 top-0 flex flex-col items-center justify-center"
>
<LoadingCircle class="mx-auto" />
</div>
</template>

<script setup lang="ts">
import { type Ref, ref } from 'vue'
import { OverviewFactory } from '@/model/factories/OverviewFactory'
import ComparisonView from '@/views/ComparisonView.vue'
import { getHighlightLanguage, type HighlightLanguage } from '@/model/Language'
import type { Comparison } from '@/model/Comparison'
import { ComparisonFactory } from '@/model/factories/ComparisonFactory'
import LoadingCircle from '@/components/LoadingCircle.vue'
const props = defineProps({
firstId: {
type: String,
required: true
},
secondId: {
type: String,
required: true
}
})
const comparison: Ref<Comparison | null> = ref(null)
const language: Ref<HighlightLanguage | null> = ref(null)
// This eslint rule is disabled to allow the use of await in the setup function. Disabling this rule is safe, because the props are gathered from the url, so changing them would reload the pafe anyway.
// eslint-disable-next-line vue/no-setup-props-reactivity-loss
ComparisonFactory.getComparison(props.firstId, props.secondId).then((comp) => {
comparison.value = comp
})
OverviewFactory.getOverview().then((overview) => {
language.value = getHighlightLanguage(overview.language)
})
</script>
23 changes: 23 additions & 0 deletions report-viewer/src/viewWrapper/InformationViewWrapper.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
<template>
<InformationView v-if="overview" :overview="overview" />
<div
v-else
class="absolute bottom-0 left-0 right-0 top-0 flex flex-col items-center justify-center"
>
<LoadingCircle class="mx-auto" />
</div>
</template>

<script setup lang="ts">
import { type Ref, ref } from 'vue'
import { OverviewFactory } from '@/model/factories/OverviewFactory'
import InformationView from '@/views/InformationView.vue'
import type { Overview } from '@/model/Overview'
import LoadingCircle from '@/components/LoadingCircle.vue'
const overview: Ref<Overview | null> = ref(null)
OverviewFactory.getOverview().then((o) => {
overview.value = o
})
</script>
23 changes: 23 additions & 0 deletions report-viewer/src/viewWrapper/OverviewViewWrapper.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
<template>
<OverviewView v-if="overview" :overview="overview" />
<div
v-else
class="absolute bottom-0 left-0 right-0 top-0 flex flex-col items-center justify-center"
>
<LoadingCircle class="mx-auto" />
</div>
</template>

<script setup lang="ts">
import { type Ref, ref } from 'vue'
import { OverviewFactory } from '@/model/factories/OverviewFactory'
import OverviewView from '@/views/OverviewView.vue'
import type { Overview } from '@/model/Overview'
import LoadingCircle from '@/components/LoadingCircle.vue'
const overview: Ref<Overview | null> = ref(null)
OverviewFactory.getOverview().then((o) => {
overview.value = o
})
</script>
36 changes: 21 additions & 15 deletions report-viewer/src/views/ClusterView.vue
Original file line number Diff line number Diff line change
Expand Up @@ -28,35 +28,39 @@ import ClusterRadarChart from '@/components/ClusterRadarChart.vue'
import ComparisonsTable from '@/components/ComparisonsTable.vue'
import Container from '@/components/ContainerComponent.vue'
import TextInformation from '@/components/TextInformation.vue'
import type { Cluster } from '@/model/Cluster'
import type { ClusterListElement, ClusterListElementMember } from '@/model/ClusterListElement'
import type { ComparisonListElement } from '@/model/ComparisonListElement'
import { MetricType } from '@/model/MetricType'
import { OverviewFactory } from '@/model/factories/OverviewFactory'
import type { Overview } from '@/model/Overview'
import { computed, type PropType, type Ref } from 'vue'
const props = defineProps({
clusterIndex: {
type: Number,
overview: {
type: Object as PropType<Overview>,
required: true
},
cluster: {
type: Object as PropType<Cluster>,
required: true
}
})
const overview = await OverviewFactory.getOverview()
const cluster = overview.clusters[props.clusterIndex]
const comparisons = [] as Array<ComparisonListElement>
const clusterMemberList = new Map() as ClusterListElementMember
const usedMetric = MetricType.AVERAGE
function getComparisonFor(id1: string, id2: string) {
return overview.topComparisons.find(
return props.overview.topComparisons.find(
(c) =>
(c.firstSubmissionId === id1 && c.secondSubmissionId === id2) ||
(c.firstSubmissionId === id2 && c.secondSubmissionId === id1)
)
}
for (let i = 0; i < cluster.members.length; i++) {
for (let j = i + 1; j < cluster.members.length; j++) {
const comparison = getComparisonFor(cluster.members[i], cluster.members[j])
for (let i = 0; i < props.cluster.members.length; i++) {
for (let j = i + 1; j < props.cluster.members.length; j++) {
const comparison = getComparisonFor(props.cluster.members[i], props.cluster.members[j])
if (comparison) {
comparisons.push(comparison)
}
Expand All @@ -70,7 +74,7 @@ comparisons
c.id = counter
})
for (const member of cluster.members) {
for (const member of props.cluster.members) {
const membersComparisons: { matchedWith: string; similarity: number }[] = []
comparisons
.filter((c) => c.firstSubmissionId === member || c.secondSubmissionId === member)
Expand All @@ -83,9 +87,11 @@ for (const member of cluster.members) {
clusterMemberList.set(member, membersComparisons)
}
const clusterListElement: ClusterListElement = {
averageSimilarity: cluster.averageSimilarity,
members: clusterMemberList,
strength: cluster.strength
}
const clusterListElement: Ref<ClusterListElement> = computed(() => {
return {
averageSimilarity: props.cluster.averageSimilarity,
members: clusterMemberList,
strength: props.cluster.strength
}
})
</script>
28 changes: 15 additions & 13 deletions report-viewer/src/views/ComparisonView.vue
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@
? 'Submission 1'
: (store().submissionDisplayName(comparison.secondSubmissionId) as string)
"
:highlight-language="getHighlightLanguage(language)"
:highlight-language="language"
@line-selected="showMatchInSecond"
class="max-h-0 min-h-full flex-1 overflow-hidden"
/>
Expand All @@ -56,7 +56,7 @@
? 'Submission 2'
: (store().submissionDisplayName(comparison.secondSubmissionId) as string)
"
:highlight-language="getHighlightLanguage(language)"
:highlight-language="language"
@line-selected="showMatchInFirst"
class="max-h-0 min-h-full flex-1 overflow-hidden"
/>
Expand All @@ -67,19 +67,18 @@
<script setup lang="ts">
import type { Match } from '@/model/Match'

import { onMounted, ref, watch, type Ref, computed, onErrorCaptured } from 'vue'
import { onMounted, ref, watch, type Ref, computed, onErrorCaptured, type PropType } from 'vue'
import TextInformation from '@/components/TextInformation.vue'
import MatchList from '@/components/MatchList.vue'
import { ComparisonFactory } from '@/model/factories/ComparisonFactory'
import FilesContainer from '@/components/FilesContainer.vue'
import { store } from '@/stores/store'
import Container from '@/components/ContainerComponent.vue'
import { getHighlightLanguage } from '@/model/Language'
import { HighlightLanguage } from '@/model/Language'
import hljsLightMode from 'highlight.js/styles/vs.css?raw'
import hljsDarkMode from 'highlight.js/styles/vs2015.css?raw'
import { router } from '@/router'
import { MetricType } from '@/model/MetricType'
import { OverviewFactory } from '@/model/factories/OverviewFactory'
import { Comparison } from '@/model/Comparison'

const props = defineProps({
firstId: {
Expand All @@ -89,16 +88,19 @@ const props = defineProps({
secondId: {
type: String,
required: true
},
comparison: {
type: Object as PropType<Comparison>,
required: true
},
language: {
type: Object as PropType<HighlightLanguage>,
required: true
}
})

// This eslint rule is disabled to allow the use of await in the setup function. Disabling this rule is safe, because the props are gathered from the url, so changing them would reload the pafe anyway.
// eslint-disable-next-line vue/no-setup-props-reactivity-loss
const comparison = await ComparisonFactory.getComparison(props.firstId, props.secondId)
const language = (await OverviewFactory.getOverview()).language

const filesOfFirst = ref(comparison.filesOfFirstSubmission)
const filesOfSecond = ref(comparison.filesOfSecondSubmission)
const filesOfFirst = computed(() => props.comparison.filesOfFirstSubmission)
const filesOfSecond = computed(() => props.comparison.filesOfSecondSubmission)

const panel1: Ref<typeof FilesContainer | null> = ref(null)
const panel2: Ref<typeof FilesContainer | null> = ref(null)
Expand Down
8 changes: 2 additions & 6 deletions report-viewer/src/views/FileUploadView.vue
Original file line number Diff line number Diff line change
Expand Up @@ -36,12 +36,7 @@
Continue with local files
</Button>
</div>
<div v-else class="space-y-5 pt-5">
<div
class="mx-auto h-16 w-16 animate-spin rounded-full border-8 border-interactable-border-light border-t-accent dark:border-interactable-border-dark dark:border-t-accent"
></div>
<p class="text-2xl font-bold">Loading file...</p>
</div>
<LoadingCircle v-else class="space-y-5 pt-5" />
</div>
<VersionInfoComponent class="absolute bottom-3 left-3" />
</div>
Expand All @@ -54,6 +49,7 @@ import { router } from '@/router'
import { store } from '@/stores/store'
import Button from '@/components/ButtonComponent.vue'
import VersionInfoComponent from '@/components/VersionInfoComponent.vue'
import LoadingCircle from '@/components/LoadingCircle.vue'
import { JsonFileHandler } from '@/utils/fileHandling/JsonFileHandler'
import { ZipFileHandler } from '@/utils/fileHandling/ZipFileHandler'

Expand Down
16 changes: 11 additions & 5 deletions report-viewer/src/views/InformationView.vue
Original file line number Diff line number Diff line change
Expand Up @@ -48,15 +48,21 @@
</template>

<script setup lang="ts">
import { OverviewFactory } from '@/model/factories/OverviewFactory'
import Container from '@/components/ContainerComponent.vue'
import TextInformation from '@/components/TextInformation.vue'
import ScrollableComponent from '@/components/ScrollableComponent.vue'
import { store } from '@/stores/store'
import { Overview } from '@/model/Overview'
import { computed, type PropType } from 'vue'
const overview = await OverviewFactory.getOverview()
const props = defineProps({
overview: {
type: Object as PropType<Overview>,
required: true
}
})
const totalComparisons = overview.totalComparisons
const shownComparisons = overview.topComparisons.length
const missingComparisons = totalComparisons - shownComparisons
const totalComparisons = computed(() => props.overview.totalComparisons)
const shownComparisons = computed(() => props.overview.topComparisons.length)
const missingComparisons = computed(() => totalComparisons.value - shownComparisons.value)
</script>
Loading

0 comments on commit 9149f42

Please sign in to comment.