diff --git a/dashboard/public/translation/en.json b/dashboard/public/translation/en.json index d698e8d2b..522c4e5c5 100644 --- a/dashboard/public/translation/en.json +++ b/dashboard/public/translation/en.json @@ -1033,6 +1033,9 @@ }, "graphs": { "title": "Graphs" + }, + "locale": { + "title": "Locale Settings" } }, "eventlog": { diff --git a/dashboard/src/Index.vue b/dashboard/src/Index.vue index dd38e6b7f..dd0d996de 100644 --- a/dashboard/src/Index.vue +++ b/dashboard/src/Index.vue @@ -270,6 +270,7 @@ onMounted(async () => { {{ $t('eventlog.title') }} + {{ $t('system.title') }} {{ $t('network.title') }} {{ $t('services.title') }} {{ $t('settings.title') }} @@ -282,7 +283,6 @@ onMounted(async () => { {{ $t('volumes.title') }} - {{ $t('system.title') }} diff --git a/dashboard/src/views/MetricsView.vue b/dashboard/src/views/MetricsView.vue index 4791575ec..9916c8767 100644 --- a/dashboard/src/views/MetricsView.vue +++ b/dashboard/src/views/MetricsView.vue @@ -1,116 +1,13 @@ diff --git a/dashboard/src/views/SystemView.vue b/dashboard/src/views/SystemView.vue index 51c30c102..68bde3802 100644 --- a/dashboard/src/views/SystemView.vue +++ b/dashboard/src/views/SystemView.vue @@ -4,8 +4,9 @@ import { useI18n } from 'vue-i18n'; const i18n = useI18n(); const t = i18n.t; -import { ref, onMounted } from 'vue'; -import { SingleSelect } from 'pankow'; +import { ref, useTemplateRef, onMounted } from 'vue'; +import { Button, InputDialog, SingleSelect } from 'pankow'; +import { prettyDecimalSize, sleep } from 'pankow/utils'; import moment from 'moment-timezone'; import SettingsItem from '../components/SettingsItem.vue'; import Section from '../components/Section.vue'; @@ -13,9 +14,20 @@ import CloudronAccount from '../components/CloudronAccount.vue'; import SystemUpdate from '../components/SystemUpdate.vue'; import PrivateRegistry from '../components/PrivateRegistry.vue'; import CloudronModel from '../models/CloudronModel.js'; +import DashboardModel from '../models/DashboardModel.js'; +import SystemModel from '../models/SystemModel.js'; +const systemModel = SystemModel.create(); +const dashboardModel = DashboardModel.create(); const cloudronModel = CloudronModel.create(); +const config = ref({}); +const info = ref({}); +const uptime = ref(''); +const activeSince = ref(''); +const memory = ref({}); +const cpus = ref({}); + // Timezone const allTimezones = moment.tz.names().map(t => { return { id: t }; }); const timeZone = ref(''); @@ -40,8 +52,38 @@ async function onLanguageChange(value) { currentLanguage.value = value; } +const inputDialog = useTemplateRef('inputDialog'); +async function onReboot() { + const confirmed = await inputDialog.value.confirm({ + title: t('main.rebootDialog.title'), + message: t('main.rebootDialog.description'), + confirmLabel: t('main.rebootDialog.rebootAction'), + confirmStyle: 'danger', + rejectLabel: t('main.dialog.cancel'), + }); + + if (!confirmed) return; + + await systemModel.reboot(); + + // now poll until the backend does not respond anymore to trigger the unreachable overlay + while (true) { + const [error] = await dashboardModel.config(); + if (error) break; + await sleep(1000); + } +} + onMounted(async () => { - let [error, result] = await cloudronModel.getTimeZone(); + let [error, result] = await systemModel.memory(); + if (error) return console.error(error); + memory.value = result; + + [error, result] = await systemModel.cpus(); + if (error) return console.error(error); + cpus.value = result; + + [error, result] = await cloudronModel.getTimeZone(); if (error) return console.error(error); timeZone.value = result; @@ -62,13 +104,63 @@ onMounted(async () => { language.value = result; currentLanguage.value = result; + + [error, result] = await systemModel.info(); + if (error) return console.error(error); + info.value = result; + + uptime.value = moment.duration(info.value.uptimeSecs, 'seconds').locale(navigator.language).humanize(); + activeSince.value = info.value.activationTime ? moment(info.value.activationTime).fromNow() : 'unknown'; + + [error, result] = await dashboardModel.config(); + if (error) return console.error(error); + config.value = result; });