Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add toast for new version notification #1892

Merged
merged 4 commits into from
Aug 2, 2024
Merged
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
49 changes: 49 additions & 0 deletions report-viewer/src/App.vue
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,15 @@
:icon="store().uiState.useDarkMode ? ['fas', 'sun'] : ['fas', 'moon']"
/>
</Button>
<ToastComponent v-if="showToast" :time-to-live="10000">
You are using an outdated version of the JPlag Report Viewer ({{
reportViewerVersion.toString()
}}).<br />
Version {{ newestVersion.toString() }} is available on
<a href="https://github.com/jplag/JPlag/releases/latest" class="text-link underline"
>GitHub</a
>.
</ToastComponent>
</div>
</div>
</template>
Expand All @@ -25,7 +34,47 @@ import { FontAwesomeIcon } from '@fortawesome/vue-fontawesome'
import { library } from '@fortawesome/fontawesome-svg-core'
import { faMoon, faSun } from '@fortawesome/free-solid-svg-icons'
import { store } from './stores/store'
import ToastComponent from './components/ToastComponent.vue'
import { Version, reportViewerVersion } from './model/Version'
import { computed, ref } from 'vue'

library.add(faMoon)
library.add(faSun)

const newestVersion = ref(new Version(-1, -1, -1))
Kr0nox marked this conversation as resolved.
Show resolved Hide resolved
const isDemo = import.meta.env.MODE == 'demo'
const hasShownToast = ref(sessionStorage.getItem('hasShownToast') == 'true')

const showToast = computed(() => {
const value =
!isDemo &&
!newestVersion.value.isInvalid() &&
!reportViewerVersion.isDevVersion() &&
newestVersion.value.compareTo(reportViewerVersion) > 0 &&
!hasShownToast.value

if (value) {
sessionStorage.setItem('hasShownToast', 'true')
} else {
sessionStorage.removeItem('hasShownToast')
}

return value
})

fetch('https://api.github.com/repos/jplag/JPlag/releases/latest')
.then((response) => response.json())
.then((data) => {
const versionString = data.tag_name
// remove the 'v' from the version string and split it into an array
const versionArray = versionString.substring(1).split('.')
newestVersion.value = new Version(
parseInt(versionArray[0]),
parseInt(versionArray[1]),
parseInt(versionArray[2])
)
})
.catch(() => {
newestVersion.value = new Version(-1, -1, -1)
})
</script>
25 changes: 0 additions & 25 deletions report-viewer/src/components/RepositoryReference.vue

This file was deleted.

45 changes: 45 additions & 0 deletions report-viewer/src/components/ToastComponent.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
<template>
<div
class="absolute bottom-5 left-5 max-w-96 rounded-md border-2 border-accent-dark bg-container-light dark:bg-container-dark"
v-if="timePassed < timeToLive && visible"
>
<div class="flex">
<div class="flex-grow p-2">
<slot></slot>
</div>
<div class="cursor-pointer p-1" @click="visible = false">
<FontAwesomeIcon :icon="faTimes" />
</div>
</div>
<div
class="h-1 bg-accent"
:style="{ width: `${100 - (timePassed / timeToLive) * 100}%` }"
></div>
</div>
</template>

<script setup lang="ts">
import { FontAwesomeIcon } from '@fortawesome/vue-fontawesome'
import { ref } from 'vue'
import { faTimes } from '@fortawesome/free-solid-svg-icons'

const props = defineProps({
timeToLive: {
type: Number,
required: false,
default: 5000
}
})

const timePassed = ref(0)
const visible = ref(true)

const intervalTime = 20

const intervalID = setInterval(() => {
timePassed.value += intervalTime
if (timePassed.value >= props.timeToLive) {
clearInterval(intervalID)
}
}, intervalTime)
</script>
36 changes: 4 additions & 32 deletions report-viewer/src/components/VersionInfoComponent.vue
Original file line number Diff line number Diff line change
Expand Up @@ -7,17 +7,7 @@
</div>

<div v-else>
<div v-if="newestVersion.compareTo(reportViewerVersion) > 0" class="text-left text-error">
You are using an outdated version of the JPlag Report Viewer ({{
reportViewerVersion.toString()
}}).<br />
Version {{ newestVersion.toString() }} is available on
<a href="https://github.com/jplag/JPlag/releases/latest" class="text-link underline"
>GitHub</a
>.
</div>

<div v-else>JPlag v{{ reportViewerVersion.toString() }}</div>
JPlag v{{ reportViewerVersion.toString() }}

<div v-if="!minimalReportVersion.isInvalid()">
The minimal version of JPlag that is supported by the viewer is v{{
Expand All @@ -32,31 +22,13 @@
<div v-else>Demo of JPlag v{{ reportViewerVersion.toString() }}</div>
<div>Displays the result of JPlag on the Progpedia dataset.</div>
</div>
<RepositoryReference :override-style="false" />
<VersionRepositoryReference :show-version="false" :override-style="false" />
</div>
</template>

<script setup lang="ts">
import { ref } from 'vue'
import { minimalReportVersion, reportViewerVersion, Version } from '@/model/Version'
import RepositoryReference from './RepositoryReference.vue'
import { minimalReportVersion, reportViewerVersion } from '@/model/Version'
import VersionRepositoryReference from './VersionRepositoryReference.vue'

const newestVersion = ref(new Version(-1, -1, -1))
const isDemo = import.meta.env.MODE == 'demo'

fetch('https://api.github.com/repos/jplag/JPlag/releases/latest')
.then((response) => response.json())
.then((data) => {
const versionString = data.tag_name
// remove the 'v' from the version string and split it into an array
const versionArray = versionString.substring(1).split('.')
newestVersion.value = new Version(
parseInt(versionArray[0]),
parseInt(versionArray[1]),
parseInt(versionArray[2])
)
})
.catch(() => {
newestVersion.value = new Version(-1, -1, -1)
})
</script>
40 changes: 40 additions & 0 deletions report-viewer/src/components/VersionRepositoryReference.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
<template>
<div
:class="{
'absolute bottom-1 left-5 space-x-2 text-xs text-black dark:text-white print:hidden':
overrideStyle
}"
>
<span
v-if="!reportViewerVersion.isDevVersion() && !reportViewerVersion.isInvalid() && showVersion"
>JPlag v{{ reportViewerVersion.toString() }}</span
>
<span>
JPlag is open source. Bug reports and feature requests can be submitted on
<a
href="https://github.com/jplag/JPlag/issues"
class="text-link-dark underline dark:text-link"
><FontAwesomeIcon :icon="faGithub" /> GitHub</a
>
</span>
</div>
</template>

<script setup lang="ts">
import { FontAwesomeIcon } from '@fortawesome/vue-fontawesome'
import { faGithub } from '@fortawesome/free-brands-svg-icons'
import { reportViewerVersion } from '@/model/Version'

defineProps({
overrideStyle: {
type: Boolean,
required: false,
default: true
},
showVersion: {
type: Boolean,
required: false,
default: true
}
})
</script>
2 changes: 1 addition & 1 deletion report-viewer/src/version.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"report_viewer_version": {
"major": 0,
"major": 5,
"minor": 0,
"patch": 0
},
Expand Down
4 changes: 2 additions & 2 deletions report-viewer/src/viewWrapper/ClusterViewWrapper.vue
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
<LoadingCircle class="mx-auto" />
</div>

<RepositoryReference />
<VersionRepositoryReference />
</div>
</template>

Expand All @@ -19,7 +19,7 @@ import ClusterView from '@/views/ClusterView.vue'
import LoadingCircle from '@/components/LoadingCircle.vue'
import type { Overview } from '@/model/Overview'
import { redirectOnError } from '@/router'
import RepositoryReference from '@/components/RepositoryReference.vue'
import VersionRepositoryReference from '@/components/VersionRepositoryReference.vue'

const props = defineProps({
clusterIndex: {
Expand Down
4 changes: 2 additions & 2 deletions report-viewer/src/viewWrapper/ComparisonViewWrapper.vue
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@
<LoadingCircle class="mx-auto" />
</div>

<RepositoryReference />
<VersionRepositoryReference />
</div>
</template>

Expand All @@ -27,7 +27,7 @@ import { ComparisonFactory } from '@/model/factories/ComparisonFactory'
import LoadingCircle from '@/components/LoadingCircle.vue'
import { redirectOnError } from '@/router'
import type { Language } from '@/model/Language'
import RepositoryReference from '@/components/RepositoryReference.vue'
import VersionRepositoryReference from '@/components/VersionRepositoryReference.vue'
import type { BaseCodeMatch } from '@/model/BaseCodeReport'
import { BaseCodeReportFactory } from '@/model/factories/BaseCodeReportFactory'

Expand Down
4 changes: 2 additions & 2 deletions report-viewer/src/viewWrapper/InformationViewWrapper.vue
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
<LoadingCircle class="mx-auto" />
</div>

<RepositoryReference />
<VersionRepositoryReference />
</div>
</template>

Expand All @@ -21,7 +21,7 @@ import LoadingCircle from '@/components/LoadingCircle.vue'
import { redirectOnError } from '@/router'
import { OptionsFactory } from '@/model/factories/OptionsFactory'
import type { CliOptions } from '@/model/CliOptions'
import RepositoryReference from '@/components/RepositoryReference.vue'
import VersionRepositoryReference from '@/components/VersionRepositoryReference.vue'

const overview: Ref<Overview | null> = ref(null)
const cliOptions: Ref<CliOptions | undefined> = ref(undefined)
Expand Down
4 changes: 2 additions & 2 deletions report-viewer/src/viewWrapper/OverviewViewWrapper.vue
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
<LoadingCircle class="mx-auto" />
</div>

<RepositoryReference />
<VersionRepositoryReference />
</div>
</template>

Expand All @@ -19,7 +19,7 @@ import OverviewView from '@/views/OverviewView.vue'
import type { Overview } from '@/model/Overview'
import LoadingCircle from '@/components/LoadingCircle.vue'
import { redirectOnError } from '@/router'
import RepositoryReference from '@/components/RepositoryReference.vue'
import VersionRepositoryReference from '@/components/VersionRepositoryReference.vue'

const overview: Ref<Overview | null> = ref(null)

Expand Down
14 changes: 0 additions & 14 deletions report-viewer/tests/unit/components/VersionInfoComponent.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -19,20 +19,6 @@ describe('VersionInfoComponent', () => {
)
})

it('Render outdated version', async () => {
vi.spyOn(versionTsFile, 'reportViewerVersion', 'get').mockReturnValue(mockVersionJSON(4, 3, 0))
vi.spyOn(versionTsFile, 'minimalReportVersion', 'get').mockReturnValue(mockVersionJSON(4, 0, 0))
global.fetch = vi.fn().mockResolvedValueOnce(mockVersionResponse('v4.4.0'))

const wrapper = mount(VersionInfoComponent)
await flushPromises()

expect(wrapper.text()).toContain('outdated version')
expect(wrapper.text()).toContain(
'The minimal version of JPlag that is supported by the viewer is v4.0.0.'
)
})

it('Render latest version', async () => {
vi.spyOn(versionTsFile, 'reportViewerVersion', 'get').mockReturnValue(mockVersionJSON(4, 3, 0))
vi.spyOn(versionTsFile, 'minimalReportVersion', 'get').mockReturnValue(mockVersionJSON(4, 0, 0))
Expand Down