feat: check for updates dialog

pull/6775/head
NGPixel 1 year ago
parent 57c9d37fda
commit bb4a1e6b15
No known key found for this signature in database
GPG Key ID: B755FB6870B30F63

@ -109,7 +109,7 @@ export default {
*/
async saveToDb(keys, propagate = true) {
try {
for (let key of keys) {
for (const key of keys) {
let value = get(WIKI.config, key, null)
if (!isPlainObject(value)) {
value = { v: value }

@ -98,6 +98,25 @@ export default {
return generateError(err)
}
},
async checkForUpdates (obj, args, context) {
try {
const renderJob = await WIKI.scheduler.addJob({
task: 'checkVersion',
maxRetries: 0,
promise: true
})
await renderJob.promise
return {
operation: generateSuccess('Checked for latest version successfully.'),
current: WIKI.version,
latest: WIKI.config.update.version,
latestDate: WIKI.config.update.versionDate
}
} catch (err) {
WIKI.logger.warn(err)
return generateError(err)
}
},
async disconnectWS (obj, args, context) {
WIKI.servers.ws.disconnectSockets(true)
WIKI.logger.info('All active websocket connections have been terminated.')
@ -205,13 +224,13 @@ export default {
return _.toSafeInteger(results?.total) === 0
},
latestVersion () {
return WIKI.system.updates.version
return WIKI.config.update.version
},
latestVersionReleaseDate () {
return DateTime.fromISO(WIKI.system.updates.releaseDate).toJSDate()
return DateTime.fromISO(WIKI.config.update.versionDate).toJSDate()
},
nodeVersion () {
return process.version.substr(1)
return process.version.substring(1)
},
async operatingSystem () {
let osLabel = `${os.type()} (${os.platform()}) ${os.release()} ${os.arch()}`

@ -20,6 +20,8 @@ extend type Mutation {
id: UUID!
): DefaultResponse
checkForUpdates: SystemCheckUpdateResponse
disconnectWS: DefaultResponse
installExtension(
@ -204,3 +206,10 @@ enum SystemJobState {
FAILED
INTERRUPTED
}
type SystemCheckUpdateResponse {
operation: Operation
current: String
latest: String
latestDate: String
}

@ -770,17 +770,20 @@
"admin.system.databaseHostHint": "The hostname used to access the database.",
"admin.system.dbPartialSupport": "Your database version is not fully supported. Some functionality may be limited or not work as expected.",
"admin.system.engines": "Server Engines",
"admin.system.fetchingLatestVersionInfo": "Fetching latest version info...",
"admin.system.hostInfo": "Server Host Information",
"admin.system.hostname": "Hostname",
"admin.system.hostnameHint": "The hostname of the server / container.",
"admin.system.latestVersion": "Latest Version",
"admin.system.latestVersionHint": "The latest version available to install.",
"admin.system.newVersionAvailable": "A new version is available.",
"admin.system.nodejsHint": "The version of Node.js installed.",
"admin.system.os": "Operating System",
"admin.system.osHint": "The OS Wiki.js is running on.",
"admin.system.published": "Published",
"admin.system.ramUsage": "RAM Usage: {used} / {total}",
"admin.system.refreshSuccess": "System Info has been refreshed.",
"admin.system.runningLatestVersion": "You're running the latest version.",
"admin.system.subtitle": "Information about your server / client",
"admin.system.title": "System Info",
"admin.system.totalRAM": "Total RAM",

@ -3,14 +3,14 @@ export async function task (payload) {
try {
const resp = await fetch('https://api.github.com/repos/requarks/wiki/releases/latest').then(r => r.json())
const strictVersion = resp.tag_name.indexOf('v') === 0 ? resp.tag_name.substring(1) : resp.tag_name
WIKI.logger.info(`Latest version is ${resp.tag_name}.`)
await WIKI.db.knex('settings').where('key', 'update').update({
value: {
lastCheckedAt: (new Date).toISOString(),
version: resp.tag_name,
versionDate: resp.published_at
}
})
WIKI.config.update = {
lastCheckedAt: (new Date).toISOString(),
version: strictVersion,
versionDate: resp.published_at
}
await WIKI.config.saveToDb(['update'])
WIKI.logger.info('Checked for latest version: [ COMPLETED ]')
} catch (err) {

@ -7,17 +7,25 @@ q-dialog(ref='dialogRef', @hide='onDialogHide')
q-card-section
.q-pa-md.text-center
img(src='/_assets/illustrations/undraw_going_up.svg', style='width: 150px;')
q-linear-progress(
indeterminate
size='lg'
rounded
)
.q-mt-sm.text-center.text-caption Fetching latest version info...
template(v-if='state.isLoading')
q-linear-progress(
indeterminate
size='lg'
rounded
)
.q-mt-sm.text-center.text-caption {{ $t('admin.system.fetchingLatestVersionInfo') }}
template(v-else)
.text-center
strong.text-positive(v-if='isLatest') {{ $t('admin.system.runningLatestVersion') }}
strong.text-pink(v-else) {{ $t('admin.system.newVersionAvailable') }}
.text-body2.q-mt-md Current: #[strong {{ state.current }}]
.text-body2 Latest: #[strong {{ state.latest }}]
.text-body2 Release Date: #[strong {{ state.latestDate }}]
q-card-actions.card-actions
q-space
q-btn.acrylic-btn(
flat
:label='t(`common.actions.cancel`)'
:label='state.isLoading ? t(`common.actions.cancel`) : t(`common.actions.close`)'
color='grey'
padding='xs md'
@click='onDialogCancel'
@ -37,7 +45,10 @@ q-dialog(ref='dialogRef', @hide='onDialogHide')
import gql from 'graphql-tag'
import { useI18n } from 'vue-i18n'
import { useDialogPluginComponent, useQuasar } from 'quasar'
import { reactive } from 'vue'
import { computed, onMounted, reactive } from 'vue'
import { DateTime } from 'luxon'
import { useUserStore } from 'src/stores/user'
// EMITS
@ -50,6 +61,10 @@ defineEmits([
const { dialogRef, onDialogHide, onDialogOK, onDialogCancel } = useDialogPluginComponent()
const $q = useQuasar()
// STORES
const userStore = useUserStore()
// I18N
const { t } = useI18n()
@ -58,44 +73,56 @@ const { t } = useI18n()
const state = reactive({
isLoading: false,
canUpgrade: false
canUpgrade: false,
current: '',
latest: '',
latestDate: ''
})
const isLatest = computed(() => {
return true
})
// METHODS
async function upgrade () {
async function check () {
state.isLoading = true
try {
const resp = await APOLLO_CLIENT.mutate({
mutation: gql`
mutation deleteHook ($id: UUID!) {
deleteHook(id: $id) {
mutation checkForUpdates {
checkForUpdates {
operation {
succeeded
message
}
current
latest
latestDate
}
}
`,
variables: {
id: 0
}
`
})
if (resp?.data?.deleteHook?.operation?.succeeded) {
$q.notify({
type: 'positive',
message: t('admin.webhooks.deleteSuccess')
})
onDialogOK()
if (resp?.data?.checkForUpdates?.operation?.succeeded) {
state.current = resp?.data?.checkForUpdates?.current
state.latest = resp?.data?.checkForUpdates?.latest
state.latestDate = DateTime.fromISO(resp?.data?.checkForUpdates?.latestDate).toFormat(userStore.preferredDateFormat)
} else {
throw new Error(resp?.data?.deleteHook?.operation?.message || 'An unexpected error occured.')
throw new Error(resp?.data?.checkForUpdates?.operation?.message || 'An unexpected error occured.')
}
} catch (err) {
$q.notify({
type: 'negative',
message: err.message
})
onDialogCancel()
}
state.isLoading = false
}
// MOUNTED
onMounted(() => {
check()
})
</script>

@ -107,28 +107,6 @@ q-page.admin-locale
.q-pa-md.text-center
img(src='/_assets/illustrations/undraw_world.svg', style='width: 80%;')
//- q-separator.q-my-sm(inset)
//- q-item
//- blueprint-icon(icon='test-passed')
//- q-item-section
//- q-item-label {{t(`admin.locale.activeNamespaces.label`)}}
//- q-item-label(caption) {{t(`admin.locale.activeNamespaces.hint`)}}
//- q-item-section
//- q-select(
//- outlined
//- :disable='!namespacing'
//- v-model='namespaces'
//- :options='installedLocales'
//- multiple
//- use-chips
//- option-value='code'
//- option-label='name'
//- emit-value
//- map-options
//- dense
//- :aria-label='t(`admin.locale.activeNamespaces.label`)'
//- )
</template>
<script setup>

@ -60,7 +60,7 @@ q-page.admin-system
q-item-section
.row.q-col-gutter-sm
.col
.dark-value(caption) {{ state.info.latestVersion }}
.text-caption.dark-value {{ state.info.latestVersion }}
.col-auto
q-btn.acrylic-btn(
flat
@ -200,43 +200,6 @@ q-page.admin-system
q-item-label(caption) {{t('admin.system.configFileHint')}}
q-item-section
q-item-label.dark-value(caption) {{ state.info.configFile }}
//- v-list-item-action-text {{ t('admin.system.published') }} {{ state.info.latestVersionReleaseDate | moment('from') }}
//- v-card-actions(v-if='info.upgradeCapable && !isLatestVersion && info.platform === `docker`', :class='$vuetify.theme.dark ? `grey darken-3-d5` : `indigo lighten-5`')
//- .caption.indigo--text.pl-3(:class='$vuetify.theme.dark ? `text--lighten-4` : ``') Wiki.js can perform the upgrade to the latest version for you.
//- v-spacer
//- v-btn.px-3(
//- color='indigo'
//- dark
//- @click='performUpgrade'
//- )
//- v-icon(left) mdi-upload
//- span Perform Upgrade
//- v-dialog(
//- v-model='isUpgrading'
//- persistent
//- width='450'
//- )
//- v-card.blue.darken-5(dark)
//- v-card-text.text-center.pa-10
//- self-building-square-spinner(
//- :animation-duration='4000'
//- :size='40'
//- color='#FFF'
//- style='margin: 0 auto;'
//- )
//- .body-2.mt-5.blue--text.text--lighten-4 Your Wiki.js container is being upgraded...
//- .caption.blue--text.text--lighten-2 Please wait
//- v-progress-linear.mt-5(
//- color='blue lighten-2'
//- :value='upgradeProgress'
//- :buffer-value='upgradeProgress'
//- rounded
//- :stream='isUpgradingStarted'
//- query
//- :indeterminate='!isUpgradingStarted'
//- )
</template>
<script setup>
@ -309,9 +272,6 @@ const platformLogo = computed(() => {
return 'washing-machine'
}
})
const isLatestVersion = computed(() => {
return state.info.currentVersion === state.info.latestVersion
})
const clientBrowser = computed(() => {
return !import.meta.env.SSR ? navigator.userAgent : ''
})
@ -364,51 +324,11 @@ async function load () {
function checkForUpdates () {
$q.dialog({
component: CheckUpdateDialog
}).onDismiss(() => {
load()
})
}
// async function performUpgrade () {
// state.isUpgrading = true
// state.isUpgradingStarted = false
// state.upgradeProgress = 0
// this.$store.commit('loadingStart', 'admin-system-upgrade')
// try {
// const respRaw = await APOLLO_CLIENT.mutate({
// mutation: gql`
// mutation performUpdate {
// system {
// performUpgrade {
// responseResult {
// succeeded
// errorCode
// slug
// message
// }
// }
// }
// }
// `
// })
// const resp = _get(respRaw, 'data.system.performUpgrade.responseResult', {})
// if (resp.succeeded) {
// this.isUpgradingStarted = true
// const progressInterval = setInterval(() => {
// this.upgradeProgress += 0.83
// }, 500)
// setTimeout(() => {
// clearInterval(progressInterval)
// window.location.reload(true)
// }, 60000)
// } else {
// throw new Error(resp.message)
// }
// } catch (err) {
// this.$store.commit('pushGraphError', err)
// this.$store.commit('loadingStop', 'admin-system-upgrade')
// this.isUpgrading = false
// }
// }
// MOUNTED
onMounted(() => {

Loading…
Cancel
Save