mirror of
https://github.com/Sebclem/hassio-nextcloud-backup.git
synced 2024-11-29 12:24:52 +01:00
[Front] Add basic status report
This commit is contained in:
parent
8db47b5687
commit
18446ca610
@ -8,4 +8,5 @@
|
|||||||
"javascript.inlayHints.propertyDeclarationTypes.enabled": true,
|
"javascript.inlayHints.propertyDeclarationTypes.enabled": true,
|
||||||
"javascript.inlayHints.parameterNames.suppressWhenArgumentMatchesName": true,
|
"javascript.inlayHints.parameterNames.suppressWhenArgumentMatchesName": true,
|
||||||
"javascript.inlayHints.parameterNames.enabled": "literals",
|
"javascript.inlayHints.parameterNames.enabled": "literals",
|
||||||
}
|
"editor.formatOnSave": true
|
||||||
|
}
|
||||||
|
@ -1,3 +1,3 @@
|
|||||||
{
|
{
|
||||||
"recommendations": ["Vue.volar", "Vue.vscode-typescript-vue-plugin"]
|
"recommendations": ["Vue.volar"]
|
||||||
}
|
}
|
||||||
|
1
nextcloud_backup/frontend/components.d.ts
vendored
1
nextcloud_backup/frontend/components.d.ts
vendored
@ -26,6 +26,7 @@ declare module 'vue' {
|
|||||||
NavbarComponent: typeof import('./src/components/NavbarComponent.vue')['default']
|
NavbarComponent: typeof import('./src/components/NavbarComponent.vue')['default']
|
||||||
RouterLink: typeof import('vue-router')['RouterLink']
|
RouterLink: typeof import('vue-router')['RouterLink']
|
||||||
RouterView: typeof import('vue-router')['RouterView']
|
RouterView: typeof import('vue-router')['RouterView']
|
||||||
|
StatusComponent: typeof import('./src/components/StatusComponent.vue')['default']
|
||||||
WebdavConfigForm: typeof import('./src/components/settings/WebdavConfigForm.vue')['default']
|
WebdavConfigForm: typeof import('./src/components/settings/WebdavConfigForm.vue')['default']
|
||||||
WebdavConfigMenu: typeof import('./src/components/settings/WebdavConfigMenu.vue')['default']
|
WebdavConfigMenu: typeof import('./src/components/settings/WebdavConfigMenu.vue')['default']
|
||||||
}
|
}
|
||||||
|
@ -21,6 +21,7 @@
|
|||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@babel/types": "^7.23.0",
|
"@babel/types": "^7.23.0",
|
||||||
|
"@types/luxon": "^3.4.2",
|
||||||
"@types/node": "^20.10.0",
|
"@types/node": "^20.10.0",
|
||||||
"@vitejs/plugin-vue": "^4.5.0",
|
"@vitejs/plugin-vue": "^4.5.0",
|
||||||
"@vue/eslint-config-typescript": "^12.0.0",
|
"@vue/eslint-config-typescript": "^12.0.0",
|
||||||
@ -46,4 +47,4 @@
|
|||||||
"vue-tsc": "^1.8.0"
|
"vue-tsc": "^1.8.0"
|
||||||
},
|
},
|
||||||
"packageManager": "pnpm@8.15.3"
|
"packageManager": "pnpm@8.15.3"
|
||||||
}
|
}
|
7
nextcloud_backup/frontend/pnpm-lock.yaml
generated
7
nextcloud_backup/frontend/pnpm-lock.yaml
generated
@ -37,6 +37,9 @@ devDependencies:
|
|||||||
'@babel/types':
|
'@babel/types':
|
||||||
specifier: ^7.23.0
|
specifier: ^7.23.0
|
||||||
version: 7.23.9
|
version: 7.23.9
|
||||||
|
'@types/luxon':
|
||||||
|
specifier: ^3.4.2
|
||||||
|
version: 3.4.2
|
||||||
'@types/node':
|
'@types/node':
|
||||||
specifier: ^20.10.0
|
specifier: ^20.10.0
|
||||||
version: 20.11.19
|
version: 20.11.19
|
||||||
@ -526,6 +529,10 @@ packages:
|
|||||||
resolution: {integrity: sha512-dRLjCWHYg4oaA77cxO64oO+7JwCwnIzkZPdrrC71jQmQtlhM556pwKo5bUzqvZndkVbeFLIIi+9TC40JNF5hNQ==}
|
resolution: {integrity: sha512-dRLjCWHYg4oaA77cxO64oO+7JwCwnIzkZPdrrC71jQmQtlhM556pwKo5bUzqvZndkVbeFLIIi+9TC40JNF5hNQ==}
|
||||||
dev: true
|
dev: true
|
||||||
|
|
||||||
|
/@types/luxon@3.4.2:
|
||||||
|
resolution: {integrity: sha512-TifLZlFudklWlMBfhubvgqTXRzLDI5pCbGa4P8a3wPyUQSW+1xQ5eDsreP9DWHX3tjq1ke96uYG/nwundroWcA==}
|
||||||
|
dev: true
|
||||||
|
|
||||||
/@types/node@20.11.19:
|
/@types/node@20.11.19:
|
||||||
resolution: {integrity: sha512-7xMnVEcZFu0DikYjWOlRq7NTPETrm7teqUT2WkQjrTIkEgUyyGdWsj/Zg8bEJt5TNklzbPD1X3fqfsHw3SpapQ==}
|
resolution: {integrity: sha512-7xMnVEcZFu0DikYjWOlRq7NTPETrm7teqUT2WkQjrTIkEgUyyGdWsj/Zg8bEJt5TNklzbPD1X3fqfsHw3SpapQ==}
|
||||||
dependencies:
|
dependencies:
|
||||||
|
@ -6,6 +6,11 @@
|
|||||||
<backup-config-menu></backup-config-menu>
|
<backup-config-menu></backup-config-menu>
|
||||||
<alert-manager></alert-manager>
|
<alert-manager></alert-manager>
|
||||||
<v-main class="mx-12">
|
<v-main class="mx-12">
|
||||||
|
<v-row>
|
||||||
|
<v-col cols="4" offset="1">
|
||||||
|
<status-component></status-component>
|
||||||
|
</v-col>
|
||||||
|
</v-row>
|
||||||
<v-row>
|
<v-row>
|
||||||
<v-col cols="6">
|
<v-col cols="6">
|
||||||
<ha-list></ha-list>
|
<ha-list></ha-list>
|
||||||
|
@ -11,9 +11,7 @@
|
|||||||
class="mb-2"
|
class="mb-2"
|
||||||
>
|
>
|
||||||
<v-row dense>
|
<v-row dense>
|
||||||
<v-col>
|
<v-col v-html="alert.message"></v-col>
|
||||||
{{ alert.message }}
|
|
||||||
</v-col>
|
|
||||||
<v-col cols="2">
|
<v-col cols="2">
|
||||||
<v-btn
|
<v-btn
|
||||||
class="d-inline"
|
class="d-inline"
|
||||||
@ -54,4 +52,4 @@ const alertVisible = computed(() => alertList.value.length > 0);
|
|||||||
z-index: 99999;
|
z-index: 99999;
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
@/store/alert
|
@/store/alert
|
||||||
|
130
nextcloud_backup/frontend/src/components/StatusComponent.vue
Normal file
130
nextcloud_backup/frontend/src/components/StatusComponent.vue
Normal file
@ -0,0 +1,130 @@
|
|||||||
|
<template>
|
||||||
|
<div>
|
||||||
|
<v-card class="mt-5" border elevation="10">
|
||||||
|
<v-card-title class="text-center">Status</v-card-title>
|
||||||
|
<v-divider></v-divider>
|
||||||
|
<v-card-text>
|
||||||
|
<v-row>
|
||||||
|
<v-col cols="6">
|
||||||
|
<v-card variant="elevated" border>
|
||||||
|
<v-card-text class="align-center d-flex justify-center">
|
||||||
|
<span class="me-auto">Home Assistant</span>
|
||||||
|
<v-tooltip content-class="bg-black">
|
||||||
|
<template v-slot:activator="{ props }">
|
||||||
|
<v-chip
|
||||||
|
v-bind="props"
|
||||||
|
variant="elevated"
|
||||||
|
:prepend-icon="hassProps.icon"
|
||||||
|
:color="hassProps.color"
|
||||||
|
:text="hassProps.text"
|
||||||
|
>
|
||||||
|
</v-chip>
|
||||||
|
</template>
|
||||||
|
Last check:
|
||||||
|
{{
|
||||||
|
status?.hass.last_check
|
||||||
|
? DateTime.fromISO(status.hass.last_check).toLocaleString(
|
||||||
|
DateTime.DATETIME_MED
|
||||||
|
)
|
||||||
|
: "UNKNOWN"
|
||||||
|
}}
|
||||||
|
</v-tooltip>
|
||||||
|
</v-card-text>
|
||||||
|
</v-card>
|
||||||
|
</v-col>
|
||||||
|
<v-col cols="6">
|
||||||
|
<v-card variant="elevated" border>
|
||||||
|
<v-card-text class="align-center d-flex justify-center">
|
||||||
|
<span class="me-auto">Cloud</span>
|
||||||
|
<v-tooltip content-class="bg-black">
|
||||||
|
<template v-slot:activator="{ props }">
|
||||||
|
<v-chip
|
||||||
|
v-bind="props"
|
||||||
|
variant="elevated"
|
||||||
|
:prepend-icon="webdavProps.icon"
|
||||||
|
:color="webdavProps.color"
|
||||||
|
:text="webdavProps.text"
|
||||||
|
>
|
||||||
|
</v-chip>
|
||||||
|
</template>
|
||||||
|
<span>Login: </span>
|
||||||
|
<span :class="'text-' + webdavLoggedProps.color">
|
||||||
|
{{ webdavLoggedProps.text }}
|
||||||
|
</span>
|
||||||
|
<br />
|
||||||
|
<span>Folder: </span>
|
||||||
|
<span :class="'text-' + webdavFolderProps.color">
|
||||||
|
{{ webdavFolderProps.text }}
|
||||||
|
</span>
|
||||||
|
<p>
|
||||||
|
Last check:
|
||||||
|
{{
|
||||||
|
status?.webdav.last_check
|
||||||
|
? DateTime.fromISO(
|
||||||
|
status.webdav.last_check
|
||||||
|
).toLocaleString(DateTime.DATETIME_MED)
|
||||||
|
: "UNKNOWN"
|
||||||
|
}}
|
||||||
|
</p>
|
||||||
|
</v-tooltip>
|
||||||
|
</v-card-text>
|
||||||
|
</v-card>
|
||||||
|
</v-col>
|
||||||
|
</v-row>
|
||||||
|
</v-card-text>
|
||||||
|
</v-card>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script setup lang="ts">
|
||||||
|
import { getStatus } from "@/services/statusService";
|
||||||
|
import { Status } from "@/types/status";
|
||||||
|
import { computed, ref, onBeforeUnmount } from "vue";
|
||||||
|
import { DateTime } from "luxon";
|
||||||
|
|
||||||
|
const status = ref<Status | undefined>(undefined);
|
||||||
|
|
||||||
|
function refreshStatus() {
|
||||||
|
getStatus().then((data) => {
|
||||||
|
status.value = data;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
const webdavProps = computed(() => {
|
||||||
|
if (status.value?.webdav.logged_in && status.value?.webdav.folder_created) {
|
||||||
|
return { icon: "mdi-check", text: "Ok", color: "green" };
|
||||||
|
} else {
|
||||||
|
return { icon: "mdi-alert", text: "Fail", color: "red" };
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
const webdavLoggedProps = computed(() => {
|
||||||
|
if (status.value?.webdav.logged_in) {
|
||||||
|
return { text: "Ok", color: "green" };
|
||||||
|
} else {
|
||||||
|
return { text: "Fail", color: "red" };
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
const webdavFolderProps = computed(() => {
|
||||||
|
if (status.value?.webdav.folder_created) {
|
||||||
|
return { text: "Ok", color: "green" };
|
||||||
|
} else {
|
||||||
|
return { text: "Fail", color: "red" };
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
const hassProps = computed(() => {
|
||||||
|
if (status.value?.hass.ok) {
|
||||||
|
return { icon: "mdi-check", text: "Ok", color: "green" };
|
||||||
|
} else {
|
||||||
|
return { icon: "mdi-alert", text: "Fail", color: "red" };
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
refreshStatus();
|
||||||
|
const interval = setInterval(refreshStatus, 2000);
|
||||||
|
onBeforeUnmount(() => {
|
||||||
|
clearInterval(interval);
|
||||||
|
});
|
||||||
|
</script>
|
@ -63,7 +63,9 @@ function refreshBackup() {
|
|||||||
getBackups().then((value) => {
|
getBackups().then((value) => {
|
||||||
backups.value = value;
|
backups.value = value;
|
||||||
loading.value = false;
|
loading.value = false;
|
||||||
});
|
}).catch(()=> {
|
||||||
|
loading.value = false;
|
||||||
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
refreshBackup();
|
refreshBackup();
|
||||||
|
7
nextcloud_backup/frontend/src/services/statusService.ts
Normal file
7
nextcloud_backup/frontend/src/services/statusService.ts
Normal file
@ -0,0 +1,7 @@
|
|||||||
|
import type { WebdavBackup } from "@/types/webdav";
|
||||||
|
import kyClient from "./kyClient";
|
||||||
|
import { Status } from "@/types/status";
|
||||||
|
|
||||||
|
export function getStatus() {
|
||||||
|
return kyClient.get("status").json<Status>();
|
||||||
|
}
|
32
nextcloud_backup/frontend/src/types/status.ts
Normal file
32
nextcloud_backup/frontend/src/types/status.ts
Normal file
@ -0,0 +1,32 @@
|
|||||||
|
import type { DateTime } from "luxon";
|
||||||
|
|
||||||
|
export enum States {
|
||||||
|
IDLE = "IDLE",
|
||||||
|
BKUP_CREATION = "BKUP_CREATION",
|
||||||
|
BKUP_DOWNLOAD_HA = "BKUP_DOWNLOAD_HA",
|
||||||
|
BKUP_DOWNLOAD_CLOUD = "BKUP_DOWNLOAD_CLOUD",
|
||||||
|
BKUP_UPLOAD_HA = "BKUP_UPLOAD_HA",
|
||||||
|
BKUP_UPLOAD_CLOUD = "BKUP_UPLOAD_CLOUD",
|
||||||
|
STOP_ADDON = "STOP_ADDON",
|
||||||
|
START_ADDON = "START_ADDON",
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface Status {
|
||||||
|
status: States;
|
||||||
|
progress?: number;
|
||||||
|
last_backup: {
|
||||||
|
success?: boolean;
|
||||||
|
last_success?: string;
|
||||||
|
message?: string;
|
||||||
|
};
|
||||||
|
next_backup?: string;
|
||||||
|
webdav: {
|
||||||
|
logged_in: boolean;
|
||||||
|
folder_created: boolean;
|
||||||
|
last_check: string;
|
||||||
|
};
|
||||||
|
hass: {
|
||||||
|
ok: boolean;
|
||||||
|
last_check: string;
|
||||||
|
};
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user