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

Show Central version in modal #1099

Draft
wants to merge 1 commit into
base: master
Choose a base branch
from
Draft
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
34 changes: 20 additions & 14 deletions src/components/app.vue
Original file line number Diff line number Diff line change
Expand Up @@ -45,9 +45,10 @@ import Navbar from './navbar.vue';
import useCallWait from '../composables/call-wait';
import useDisabled from '../composables/disabled';
import useFeatureFlags from '../composables/feature-flags';
import { loadAsync } from '../util/load-async';
import { noop } from '../util/util';
import { useRequestData } from '../request-data';
import { useSessions } from '../util/session';
import { loadAsync } from '../util/load-async';

export default {
name: 'App',
Expand All @@ -73,9 +74,12 @@ export default {

const { features } = useFeatureFlags();

const { centralVersion } = useRequestData();
const { centralVersion, createResource } = useRequestData();
// Used to re-fetch version.txt in order to check for a version change.
const latestVersion = createResource('latestVersion');

const { callWait } = useCallWait();
return { visiblyLoggedIn, centralVersion, callWait, features };
return { visiblyLoggedIn, centralVersion, latestVersion, callWait, features };
},
computed: {
routerReady() {
Expand All @@ -87,23 +91,28 @@ export default {
},
},
created() {
setTimeout(this.requestVersion, 15000);
this.callWait('checkVersion', this.checkVersion, (tries) =>
(tries === 0 ? 15000 : 60000));
(tries === 0 ? 75000 : 60000));
},
// Reset backgroundColor after each test.
beforeUnmount() {
document.documentElement.style.backgroundColor = '';
},
methods: {
checkVersion() {
const previousVersion = this.centralVersion.versionText;
return this.centralVersion.request({
requestVersion() {
this.centralVersion.request({
url: '/version.txt',
clear: false,
resend: false,
alert: false
})
}).catch(noop);
},
checkVersion() {
if (!this.centralVersion.dataExists)
return !this.centralVersion.awaitingResponse;
return this.latestVersion.request({ url: '/version.txt', alert: false })
.then(() => {
if (previousVersion == null || this.centralVersion.versionText === previousVersion)
if (this.latestVersion.data === this.centralVersion.versionText)
return false;

// Alert the user about the version change, then keep alerting them.
Expand All @@ -116,10 +125,7 @@ export default {
);
return true;
})
// This error could be the result of logout, which will cancel all
// requests.
.catch(error =>
(error.response != null && error.response.status === 404));
.catch(noop);
},
hideAlertAfterClick(event) {
if (this.alert.state && event.target.closest('a[target="_blank"]') != null &&
Expand Down
75 changes: 75 additions & 0 deletions src/components/central-version.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,75 @@
<!--
Copyright 2024 ODK Central Developers
See the NOTICE file at the top-level directory of this distribution and at
https://github.com/getodk/central-frontend/blob/master/NOTICE.

This file is part of ODK Central. It is subject to the license terms in
the LICENSE file found in the top-level directory of this distribution and at
https://www.apache.org/licenses/LICENSE-2.0. No part of ODK Central,
including this file, may be copied, modified, propagated, or distributed
except according to the terms contained in the LICENSE file.
-->
<template>
<modal id="central-version" :state="state" hideable backdrop
@hide="$emit('hide')">
<template #title>{{ $t('title') }}</template>
<template #body>
<loading :state="centralVersion.initiallyLoading"/>
<div v-if="centralVersion.dataExists" class="modal-introduction">
<p>{{ $t('shortVersion', { version: centralVersion.currentVersion }) }}</p>
<p>{{ $t('longVersion') }}</p>
<pre><code><selectable wrap>{{ centralVersion.versionText }}</selectable></code></pre>
</div>
<div class="modal-actions">
<button type="button" class="btn btn-primary" @click="$emit('hide')">
{{ $t('action.close') }}
</button>
</div>
</template>
</modal>
</template>

<script setup>
import { watch } from 'vue';

import Loading from './loading.vue';
import Modal from './modal.vue';
import Selectable from './selectable.vue';

import { noop } from '../util/util';
import { useRequestData } from '../request-data';

defineOptions({
name: 'CentralVersion'
});
const props = defineProps({
state: Boolean
});
defineEmits(['hide']);

const { centralVersion } = useRequestData();

watch(() => props.state, (state) => {
if (state)
centralVersion.request({ url: '/version.txt', resend: false })
.catch(noop);
});
</script>

<style lang="scss">
#central-version {
.loading { min-height: 120px; }
}
</style>

<i18n lang="json5">
{
"en": {
// This is the title at the top of a pop-up. It refers to the version of ODK
// Central that the user is using.
"title": "Central Version",
"shortVersion": "You are using version {version} of ODK Central.",
"longVersion": "You can find more detailed version information below:"
}
}
</i18n>
7 changes: 6 additions & 1 deletion src/components/navbar.vue
Original file line number Diff line number Diff line change
Expand Up @@ -32,14 +32,16 @@ except according to the terms contained in the LICENSE file.
{{ $t('analyticsNotice') }}
</a>
<ul class="nav navbar-nav">
<navbar-help-dropdown/>
<navbar-help-dropdown @show-version="versionModal.show()"/>
<navbar-locale-dropdown/>
<navbar-actions/>
</ul>
</div>
</div>
</div>
</nav>

<central-version v-bind="versionModal" @hide="versionModal.hide()"/>
<analytics-introduction v-if="config.loaded && config.showsAnalytics"
v-bind="analyticsIntroduction" @hide="analyticsIntroduction.hide()"/>
</div>
Expand All @@ -48,6 +50,7 @@ except according to the terms contained in the LICENSE file.
<script>
import { defineAsyncComponent } from 'vue';

import CentralVersion from './central-version.vue';
import NavbarActions from './navbar/actions.vue';
import NavbarHelpDropdown from './navbar/help-dropdown.vue';
import NavbarLinks from './navbar/links.vue';
Expand All @@ -62,6 +65,7 @@ export default {
name: 'Navbar',
components: {
AnalyticsIntroduction: defineAsyncComponent(loadAsync('AnalyticsIntroduction')),
CentralVersion,
NavbarActions,
NavbarHelpDropdown,
NavbarLinks,
Expand All @@ -77,6 +81,7 @@ export default {
},
data() {
return {
versionModal: modalData(),
analyticsIntroduction: modalData('AnalyticsIntroduction')
};
},
Expand Down
5 changes: 4 additions & 1 deletion src/components/navbar/help-dropdown.vue
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,9 @@ except according to the terms contained in the LICENSE file.
<a href="https://forum.getodk.org/" target="_blank">{{ $t('common.forum') }}</a>
</li>
<li>
<a href="/version.txt" target="_blank">{{ $t('common.version') }}</a>
<a href="#" @click.prevent="$emit('show-version')">
{{ $t('common.version') }}
</a>
</li>
</ul>
</li>
Expand All @@ -35,6 +37,7 @@ import DocLink from '../doc-link.vue';
defineOptions({
name: 'NavbarHelpDropdown'
});
defineEmits(['show-version']);
</script>

<i18n lang="json5">
Expand Down
13 changes: 10 additions & 3 deletions src/components/selectable.vue
Original file line number Diff line number Diff line change
Expand Up @@ -10,14 +10,18 @@ including this file, may be copied, modified, propagated, or distributed
except according to the terms contained in the LICENSE file.
-->
<template>
<div ref="el" class="selectable" @click="select"><!-- eslint-disable-line vuejs-accessibility/click-events-have-key-events, vue/multiline-html-element-content-newline -->
<div ref="el" class="selectable" :class="{ scroll: !wrap }" @click="select"><!-- eslint-disable-line vuejs-accessibility/click-events-have-key-events, vue/multiline-html-element-content-newline -->
<slot></slot>
</div>
</template>

<script setup>
import { ref } from 'vue';

defineProps({
wrap: Boolean
});

const el = ref(null);
const select = () => {
const selection = getSelection();
Expand All @@ -31,7 +35,10 @@ const select = () => {

.selectable {
font-family: $font-family-monospace;
overflow-x: auto;
white-space: nowrap;

&.scroll {
overflow-x: auto;
white-space: nowrap;
}
}
</style>
5 changes: 3 additions & 2 deletions src/main.js
Original file line number Diff line number Diff line change
Expand Up @@ -15,15 +15,16 @@ import { createApp } from 'vue';
// components' styles.
import './styles';

import App from './components/app.vue';

import createContainer from './container';
import vTooltip from './directives/tooltip';
// ./jquery must be imported before any of Bootstrap's JavaScript plugins,
// because the plugins require jQuery.
import './jquery';
import './bootstrap';

// App must be imported after the Bootstrap modal plugin.
import App from './components/app.vue';

createApp(App)
.use(createContainer())
.directive('tooltip', vTooltip)
Expand Down
12 changes: 12 additions & 0 deletions transifex/strings_en.json
Original file line number Diff line number Diff line change
Expand Up @@ -1479,6 +1479,18 @@
}
}
},
"CentralVersion": {
"title": {
"string": "Central Version",
"developer_comment": "This is the title at the top of a pop-up. It refers to the version of ODK Central that the user is using."
},
"shortVersion": {
"string": "You are using version {version} of ODK Central."
},
"longVersion": {
"string": "You can find more detailed version information below:"
}
},
"CollectQr": {
"draft": {
"string": "Temporary Testing Code",
Expand Down