mirror of
https://github.com/louislam/uptime-kuma.git
synced 2025-07-19 07:44:02 +02:00
swap in new DashboardHome.vue and add OffLineList.vue
This commit is contained in:
parent
10fd6ede1e
commit
dce8553296
3 changed files with 67 additions and 23 deletions
4
package-lock.json
generated
4
package-lock.json
generated
|
@ -1,12 +1,12 @@
|
||||||
{
|
{
|
||||||
"name": "uptime-kuma",
|
"name": "uptime-kuma",
|
||||||
"version": "2.0.0-beta.2",
|
"version": "2.0.0-beta.3",
|
||||||
"lockfileVersion": 3,
|
"lockfileVersion": 3,
|
||||||
"requires": true,
|
"requires": true,
|
||||||
"packages": {
|
"packages": {
|
||||||
"": {
|
"": {
|
||||||
"name": "uptime-kuma",
|
"name": "uptime-kuma",
|
||||||
"version": "2.0.0-beta.2",
|
"version": "2.0.0-beta.3",
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@grpc/grpc-js": "~1.8.22",
|
"@grpc/grpc-js": "~1.8.22",
|
||||||
|
|
54
src/components/OffLineList.vue
Normal file
54
src/components/OffLineList.vue
Normal file
|
@ -0,0 +1,54 @@
|
||||||
|
<template>
|
||||||
|
<div class="offline-list shadow-box mb-4">
|
||||||
|
<h3>🚨 Offline Devices</h3>
|
||||||
|
|
||||||
|
<ul class="list-unstyled" v-if="offlineMonitors.length > 0">
|
||||||
|
<li
|
||||||
|
v-for="monitor in offlineMonitors"
|
||||||
|
:key="monitor.id"
|
||||||
|
class="flashing-red mb-2"
|
||||||
|
>
|
||||||
|
<router-link :to="`/dashboard/${monitor.id}`" class="text-danger">
|
||||||
|
{{ monitor.name }}
|
||||||
|
</router-link>
|
||||||
|
</li>
|
||||||
|
</ul>
|
||||||
|
|
||||||
|
<div v-else>
|
||||||
|
✅ All devices online
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
export default {
|
||||||
|
computed: {
|
||||||
|
offlineMonitors() {
|
||||||
|
const monitors = Object.values(this.$root.monitorList || {});
|
||||||
|
const heartbeats = this.$root.lastHeartbeatList || {};
|
||||||
|
|
||||||
|
return monitors
|
||||||
|
.filter((monitor) => {
|
||||||
|
const status = heartbeats[monitor.id]?.status;
|
||||||
|
return status === 0;
|
||||||
|
})
|
||||||
|
.sort((a, b) => a.name.localeCompare(b.name));
|
||||||
|
},
|
||||||
|
},
|
||||||
|
};
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style scoped>
|
||||||
|
.flashing-red {
|
||||||
|
animation: flash 1.5s infinite;
|
||||||
|
font-weight: bold;
|
||||||
|
}
|
||||||
|
@keyframes flash {
|
||||||
|
0%, 100% {
|
||||||
|
opacity: 1;
|
||||||
|
}
|
||||||
|
50% {
|
||||||
|
opacity: 0.4;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</style>
|
|
@ -45,6 +45,9 @@
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
<!-- 🚨 Offline Devices Component -->
|
||||||
|
<OfflineList />
|
||||||
|
|
||||||
<div class="shadow-box table-shadow-box" style="overflow-x: hidden;">
|
<div class="shadow-box table-shadow-box" style="overflow-x: hidden;">
|
||||||
<table class="table table-borderless table-hover">
|
<table class="table table-borderless table-hover">
|
||||||
<thead>
|
<thead>
|
||||||
|
@ -57,7 +60,11 @@
|
||||||
</thead>
|
</thead>
|
||||||
<tbody>
|
<tbody>
|
||||||
<tr v-for="(beat, index) in displayedRecords" :key="index" :class="{ 'shadow-box': $root.windowWidth <= 550}">
|
<tr v-for="(beat, index) in displayedRecords" :key="index" :class="{ 'shadow-box': $root.windowWidth <= 550}">
|
||||||
<td class="name-column"><router-link :to="`/dashboard/${beat.monitorID}`">{{ $root.monitorList[beat.monitorID]?.name }}</router-link></td>
|
<td class="name-column">
|
||||||
|
<router-link :to="`/dashboard/${beat.monitorID}`">
|
||||||
|
{{ $root.monitorList[beat.monitorID]?.name }}
|
||||||
|
</router-link>
|
||||||
|
</td>
|
||||||
<td><Status :status="beat.status" /></td>
|
<td><Status :status="beat.status" /></td>
|
||||||
<td :class="{ 'border-0': !beat.msg }"><Datetime :value="beat.time" /></td>
|
<td :class="{ 'border-0': !beat.msg }"><Datetime :value="beat.time" /></td>
|
||||||
<td class="border-0">{{ beat.msg }}</td>
|
<td class="border-0">{{ beat.msg }}</td>
|
||||||
|
@ -89,12 +96,14 @@
|
||||||
import Status from "../components/Status.vue";
|
import Status from "../components/Status.vue";
|
||||||
import Datetime from "../components/Datetime.vue";
|
import Datetime from "../components/Datetime.vue";
|
||||||
import Pagination from "v-pagination-3";
|
import Pagination from "v-pagination-3";
|
||||||
|
import OfflineList from "../components/OfflineList.vue";
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
components: {
|
components: {
|
||||||
Datetime,
|
Datetime,
|
||||||
Status,
|
Status,
|
||||||
Pagination,
|
Pagination,
|
||||||
|
OfflineList,
|
||||||
},
|
},
|
||||||
props: {
|
props: {
|
||||||
calculatedHeight: {
|
calculatedHeight: {
|
||||||
|
@ -140,16 +149,10 @@ export default {
|
||||||
|
|
||||||
beforeUnmount() {
|
beforeUnmount() {
|
||||||
this.$root.emitter.off("newImportantHeartbeat", this.onNewImportantHeartbeat);
|
this.$root.emitter.off("newImportantHeartbeat", this.onNewImportantHeartbeat);
|
||||||
|
|
||||||
window.removeEventListener("resize", this.updatePerPage);
|
window.removeEventListener("resize", this.updatePerPage);
|
||||||
},
|
},
|
||||||
|
|
||||||
methods: {
|
methods: {
|
||||||
/**
|
|
||||||
* Updates the displayed records when a new important heartbeat arrives.
|
|
||||||
* @param {object} heartbeat - The heartbeat object received.
|
|
||||||
* @returns {void}
|
|
||||||
*/
|
|
||||||
onNewImportantHeartbeat(heartbeat) {
|
onNewImportantHeartbeat(heartbeat) {
|
||||||
if (this.page === 1) {
|
if (this.page === 1) {
|
||||||
this.displayedRecords.unshift(heartbeat);
|
this.displayedRecords.unshift(heartbeat);
|
||||||
|
@ -160,10 +163,6 @@ export default {
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
/**
|
|
||||||
* Retrieves the length of the important heartbeat list for all monitors.
|
|
||||||
* @returns {void}
|
|
||||||
*/
|
|
||||||
getImportantHeartbeatListLength() {
|
getImportantHeartbeatListLength() {
|
||||||
this.$root.getSocket().emit("monitorImportantHeartbeatListCount", null, (res) => {
|
this.$root.getSocket().emit("monitorImportantHeartbeatListCount", null, (res) => {
|
||||||
if (res.ok) {
|
if (res.ok) {
|
||||||
|
@ -173,10 +172,6 @@ export default {
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
|
|
||||||
/**
|
|
||||||
* Retrieves the important heartbeat list for the current page.
|
|
||||||
* @returns {void}
|
|
||||||
*/
|
|
||||||
getImportantHeartbeatListPaged() {
|
getImportantHeartbeatListPaged() {
|
||||||
const offset = (this.page - 1) * this.perPage;
|
const offset = (this.page - 1) * this.perPage;
|
||||||
this.$root.getSocket().emit("monitorImportantHeartbeatListPaged", null, offset, this.perPage, (res) => {
|
this.$root.getSocket().emit("monitorImportantHeartbeatListPaged", null, offset, this.perPage, (res) => {
|
||||||
|
@ -186,10 +181,6 @@ export default {
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
|
|
||||||
/**
|
|
||||||
* Updates the number of items shown per page based on the available height.
|
|
||||||
* @returns {void}
|
|
||||||
*/
|
|
||||||
updatePerPage() {
|
updatePerPage() {
|
||||||
const tableContainer = this.$refs.tableContainer;
|
const tableContainer = this.$refs.tableContainer;
|
||||||
const tableContainerHeight = tableContainer.offsetHeight;
|
const tableContainerHeight = tableContainer.offsetHeight;
|
||||||
|
@ -201,7 +192,6 @@ export default {
|
||||||
} else {
|
} else {
|
||||||
this.perPage = this.initialPerPage;
|
this.perPage = this.initialPerPage;
|
||||||
}
|
}
|
||||||
|
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
Loading…
Add table
Reference in a new issue