mirror of
				https://github.com/louislam/uptime-kuma.git
				synced 2025-11-04 13:46:13 +08:00 
			
		
		
		
	Resolve conflicts
This commit is contained in:
		
							
								
								
									
										58
									
								
								package-lock.json
									
									
									
										generated
									
									
									
								
							
							
						
						
									
										58
									
								
								package-lock.json
									
									
									
										generated
									
									
									
								
							@@ -1,12 +1,12 @@
 | 
			
		||||
{
 | 
			
		||||
    "name": "uptime-kuma",
 | 
			
		||||
    "version": "1.15.0",
 | 
			
		||||
    "version": "1.15.1",
 | 
			
		||||
    "lockfileVersion": 2,
 | 
			
		||||
    "requires": true,
 | 
			
		||||
    "packages": {
 | 
			
		||||
        "": {
 | 
			
		||||
            "name": "uptime-kuma",
 | 
			
		||||
            "version": "1.15.0",
 | 
			
		||||
            "version": "1.15.1",
 | 
			
		||||
            "license": "MIT",
 | 
			
		||||
            "dependencies": {
 | 
			
		||||
                "@fortawesome/fontawesome-svg-core": "~1.2.36",
 | 
			
		||||
@@ -26852,9 +26852,9 @@
 | 
			
		||||
            "dev": true
 | 
			
		||||
        },
 | 
			
		||||
        "postcss-scss": {
 | 
			
		||||
            "version": "4.0.2",
 | 
			
		||||
            "resolved": "https://registry.npmjs.org/postcss-scss/-/postcss-scss-4.0.2.tgz",
 | 
			
		||||
            "integrity": "sha512-xfdkU128CkKKKVAwkyt0M8OdnelJ3MRcIRAPPQkRpoPeuzWY3RIeg7piRCpZ79MK7Q16diLXMMAD9dN5mauPlQ=="
 | 
			
		||||
            "version": "4.0.3",
 | 
			
		||||
            "resolved": "https://registry.npmjs.org/postcss-scss/-/postcss-scss-4.0.3.tgz",
 | 
			
		||||
            "integrity": "sha512-j4KxzWovfdHsyxwl1BxkUal/O4uirvHgdzMKS1aWJBAV0qh2qj5qAZqpeBfVUYGWv+4iK9Az7SPyZ4fyNju1uA=="
 | 
			
		||||
        },
 | 
			
		||||
        "postcss-selector-parser": {
 | 
			
		||||
            "version": "6.0.10",
 | 
			
		||||
@@ -27072,21 +27072,15 @@
 | 
			
		||||
                    "resolved": "https://registry.npmjs.org/ws/-/ws-8.2.3.tgz",
 | 
			
		||||
                    "integrity": "sha512-wBuoj1BDpC6ZQ1B7DWQBYVLphPWkm8i9Y0/3YdHjHKHiohOJ1ws+3OccDWtH+PoC9DZD5WOTrJvNbWvjS6JWaA==",
 | 
			
		||||
                    "dev": true
 | 
			
		||||
                },
 | 
			
		||||
                "progress": {
 | 
			
		||||
                    "version": "2.0.1",
 | 
			
		||||
                    "resolved": "https://registry.npmjs.org/progress/-/progress-2.0.1.tgz",
 | 
			
		||||
                    "integrity": "sha512-OE+a6vzqazc+K6LxJrX5UPyKFvGnL5CYmq2jFGNIBWHpc4QyE49/YOumcrpQFJpfejmvRtbJzgO1zPmMCqlbBg==",
 | 
			
		||||
                    "dev": true
 | 
			
		||||
                },
 | 
			
		||||
                "ws": {
 | 
			
		||||
                    "version": "7.4.6",
 | 
			
		||||
                    "resolved": "https://registry.npmjs.org/ws/-/ws-7.4.6.tgz",
 | 
			
		||||
                    "integrity": "sha512-YmhHDO4MzaDLB+M9ym/mDA5z0naX8j7SIlT8f8z+I0VtzsRbekxEutHSme7NPS2qE8StCYQNUnfWdXta/Yu85A==",
 | 
			
		||||
                    "dev": true
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
        },
 | 
			
		||||
        "qlobber": {
 | 
			
		||||
            "version": "5.0.3",
 | 
			
		||||
            "resolved": "https://registry.npmjs.org/qlobber/-/qlobber-5.0.3.tgz",
 | 
			
		||||
            "integrity": "sha512-wW4GTZPePyh0RgOsM18oDyOUlXfurVRgoNyJfS+y7VWPyd0GYhQp5T2tycZFZjonH+hngxIfklGJhTP/ghidgQ==",
 | 
			
		||||
            "dev": true
 | 
			
		||||
        },
 | 
			
		||||
        "qrcode": {
 | 
			
		||||
            "version": "1.5.0",
 | 
			
		||||
            "resolved": "https://registry.npmjs.org/qrcode/-/qrcode-1.5.0.tgz",
 | 
			
		||||
@@ -28384,9 +28378,9 @@
 | 
			
		||||
            }
 | 
			
		||||
        },
 | 
			
		||||
        "stylelint-config-recommended": {
 | 
			
		||||
            "version": "6.0.0",
 | 
			
		||||
            "resolved": "https://registry.npmjs.org/stylelint-config-recommended/-/stylelint-config-recommended-6.0.0.tgz",
 | 
			
		||||
            "integrity": "sha512-ZorSSdyMcxWpROYUvLEMm0vSZud2uB7tX1hzBZwvVY9SV/uly4AvvJPPhCcymZL3fcQhEQG5AELmrxWqtmzacw==",
 | 
			
		||||
            "version": "7.0.0",
 | 
			
		||||
            "resolved": "https://registry.npmjs.org/stylelint-config-recommended/-/stylelint-config-recommended-7.0.0.tgz",
 | 
			
		||||
            "integrity": "sha512-yGn84Bf/q41J4luis1AZ95gj0EQwRX8lWmGmBwkwBNSkpGSpl66XcPTulxGa/Z91aPoNGuIGBmFkcM1MejMo9Q==",
 | 
			
		||||
            "dev": true
 | 
			
		||||
        },
 | 
			
		||||
        "stylelint-config-standard": {
 | 
			
		||||
@@ -29101,9 +29095,9 @@
 | 
			
		||||
            "integrity": "sha512-CmtqT4zHQwLoJEyNVaXUjjUFPUVYlXXBHfSbRCHCUjODMqrn6L293LM1nc1ELx8epitZZvecTfIqOLlSzB3d+w=="
 | 
			
		||||
        },
 | 
			
		||||
        "vue-demi": {
 | 
			
		||||
            "version": "0.10.1",
 | 
			
		||||
            "resolved": "https://registry.npmjs.org/vue-demi/-/vue-demi-0.10.1.tgz",
 | 
			
		||||
            "integrity": "sha512-L6Oi+BvmMv6YXvqv5rJNCFHEKSVu7llpWWJczqmAQYOdmPPw5PNYoz1KKS//Fxhi+4QP64dsPjtmvnYGo1jemA=="
 | 
			
		||||
            "version": "0.11.4",
 | 
			
		||||
            "resolved": "https://registry.npmjs.org/vue-demi/-/vue-demi-0.11.4.tgz",
 | 
			
		||||
            "integrity": "sha512-/3xFwzSykLW2HiiLie43a+FFgNOcokbBJ+fzvFXd0r2T8MYohqvphUyDQ8lbAwzQ3Dlcrb1c9ykifGkhSIAk6A=="
 | 
			
		||||
        },
 | 
			
		||||
        "vue-eslint-parser": {
 | 
			
		||||
            "version": "8.3.0",
 | 
			
		||||
@@ -29189,13 +29183,6 @@
 | 
			
		||||
            "requires": {
 | 
			
		||||
                "tslib": "^2.2.0",
 | 
			
		||||
                "vue-demi": "^0.11.3"
 | 
			
		||||
            },
 | 
			
		||||
            "dependencies": {
 | 
			
		||||
                "vue-demi": {
 | 
			
		||||
                    "version": "0.11.4",
 | 
			
		||||
                    "resolved": "https://registry.npmjs.org/vue-demi/-/vue-demi-0.11.4.tgz",
 | 
			
		||||
                    "integrity": "sha512-/3xFwzSykLW2HiiLie43a+FFgNOcokbBJ+fzvFXd0r2T8MYohqvphUyDQ8lbAwzQ3Dlcrb1c9ykifGkhSIAk6A=="
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
        },
 | 
			
		||||
        "vue-router": {
 | 
			
		||||
@@ -29405,9 +29392,14 @@
 | 
			
		||||
            }
 | 
			
		||||
        },
 | 
			
		||||
        "ws": {
 | 
			
		||||
            "version": "7.5.5",
 | 
			
		||||
            "resolved": "https://registry.npmjs.org/ws/-/ws-7.5.5.tgz",
 | 
			
		||||
            "integrity": "sha512-BAkMFcAzl8as1G/hArkxOxq3G7pjUqQ3gzYbLL0/5zNkph70e+lCoxBGnm6AW1+/aiNeV4fnKqZ8m4GZewmH2w==",
 | 
			
		||||
            "version": "7.5.7",
 | 
			
		||||
            "resolved": "https://registry.npmjs.org/ws/-/ws-7.5.7.tgz",
 | 
			
		||||
            "integrity": "sha512-KMvVuFzpKBuiIXW3E4u3mySRO2/mCHSyZDJQM5NQ9Q9KHWHWh0NHgfbRMLLrceUK5qAL4ytALJbpRMjixFZh8A=="
 | 
			
		||||
        },
 | 
			
		||||
        "xdg-basedir": {
 | 
			
		||||
            "version": "4.0.0",
 | 
			
		||||
            "resolved": "https://registry.npmjs.org/xdg-basedir/-/xdg-basedir-4.0.0.tgz",
 | 
			
		||||
            "integrity": "sha512-PSNhEJDejZYV7h50BohL09Er9VaIefr2LMAf3OEmpCkjOi34eYyQYAXUTjEQtZJTKcF0E2UKTh+osDLsgNim9Q==",
 | 
			
		||||
            "dev": true
 | 
			
		||||
        },
 | 
			
		||||
        "xml-name-validator": {
 | 
			
		||||
 
 | 
			
		||||
@@ -128,6 +128,8 @@ router.get("/api/status-page/:slug", cache("5 minutes"), async (request, respons
 | 
			
		||||
            incident = incident.toPublicJSON();
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        let maintenance = await getMaintenanceList();
 | 
			
		||||
 | 
			
		||||
        // Public Group List
 | 
			
		||||
        const publicGroupList = [];
 | 
			
		||||
        const showTags = !!statusPage.show_tags;
 | 
			
		||||
@@ -145,6 +147,7 @@ router.get("/api/status-page/:slug", cache("5 minutes"), async (request, respons
 | 
			
		||||
        response.json({
 | 
			
		||||
            config: await statusPage.toPublicJSON(),
 | 
			
		||||
            incident,
 | 
			
		||||
            maintenance,
 | 
			
		||||
            publicGroupList
 | 
			
		||||
        });
 | 
			
		||||
 | 
			
		||||
@@ -153,15 +156,10 @@ router.get("/api/status-page/:slug", cache("5 minutes"), async (request, respons
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
});
 | 
			
		||||
 | 
			
		||||
//TODO: make OK with new multi status pages
 | 
			
		||||
// TODO: make slug aware
 | 
			
		||||
// Status Page - Maintenance List
 | 
			
		||||
// Can fetch only if published
 | 
			
		||||
router.get("/api/status-page/maintenance-list", async (_request, response) => {
 | 
			
		||||
    allowDevAllOrigin(response);
 | 
			
		||||
 | 
			
		||||
async function getMaintenanceList() {
 | 
			
		||||
    try {
 | 
			
		||||
        await checkPublished();
 | 
			
		||||
        const publicMaintenanceList = [];
 | 
			
		||||
 | 
			
		||||
        let maintenanceBeanList = R.convertToBeans("maintenance", await R.getAll(`
 | 
			
		||||
@@ -176,12 +174,12 @@ router.get("/api/status-page/maintenance-list", async (_request, response) => {
 | 
			
		||||
            publicMaintenanceList.push(await bean.toPublicJSON());
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        response.json(publicMaintenanceList);
 | 
			
		||||
        return publicMaintenanceList;
 | 
			
		||||
 | 
			
		||||
    } catch (error) {
 | 
			
		||||
        send403(response, error.message);
 | 
			
		||||
        return null;
 | 
			
		||||
    }
 | 
			
		||||
});
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Status Page Polling Data
 | 
			
		||||
// Can fetch only if published
 | 
			
		||||
 
 | 
			
		||||
@@ -24,7 +24,7 @@ import timezone from "dayjs/plugin/timezone";
 | 
			
		||||
import utc from "dayjs/plugin/utc";
 | 
			
		||||
import { LineChart } from "vue-chart-3";
 | 
			
		||||
import { useToast } from "vue-toastification";
 | 
			
		||||
import { DOWN, MAINTENANCE } from "../util.ts";
 | 
			
		||||
import { DOWN, PENDING, MAINTENANCE } from "../util.ts";
 | 
			
		||||
 | 
			
		||||
dayjs.extend(utc);
 | 
			
		||||
dayjs.extend(timezone);
 | 
			
		||||
@@ -187,7 +187,7 @@ export default {
 | 
			
		||||
                        x,
 | 
			
		||||
                        y: (beat.status === DOWN || beat.status === MAINTENANCE || beat.status === PENDING) ? 1 : 0,
 | 
			
		||||
                    });
 | 
			
		||||
                    colorData.push((beat.status === MAINTENANCE) ? "rgba(23,71,245,0.41)" : ((beat.status === PENDING) ? "rgba(245,182,23,0.41)" : "#DC354568"))
 | 
			
		||||
                    colorData.push((beat.status === MAINTENANCE) ? "rgba(23,71,245,0.41)" : ((beat.status === PENDING) ? "rgba(245,182,23,0.41)" : "#DC354568"));
 | 
			
		||||
                });
 | 
			
		||||
 | 
			
		||||
            return {
 | 
			
		||||
 
 | 
			
		||||
@@ -42,6 +42,7 @@ import {
 | 
			
		||||
    faPlusCircle,
 | 
			
		||||
    faAngleDown,
 | 
			
		||||
    faWrench,
 | 
			
		||||
    faHeartbeat,
 | 
			
		||||
} from "@fortawesome/free-solid-svg-icons";
 | 
			
		||||
 | 
			
		||||
library.add(
 | 
			
		||||
@@ -83,6 +84,7 @@ library.add(
 | 
			
		||||
    faPlusCircle,
 | 
			
		||||
    faAngleDown,
 | 
			
		||||
    faWrench,
 | 
			
		||||
    faHeartbeat,
 | 
			
		||||
);
 | 
			
		||||
 | 
			
		||||
export { FontAwesomeIcon };
 | 
			
		||||
 
 | 
			
		||||
@@ -494,6 +494,7 @@ export default {
 | 
			
		||||
            let result = {
 | 
			
		||||
                up: 0,
 | 
			
		||||
                down: 0,
 | 
			
		||||
                maintenance: 0,
 | 
			
		||||
                unknown: 0,
 | 
			
		||||
                pause: 0,
 | 
			
		||||
            };
 | 
			
		||||
@@ -502,7 +503,10 @@ export default {
 | 
			
		||||
                let beat = this.$root.lastHeartbeatList[monitorID];
 | 
			
		||||
                let monitor = this.$root.monitorList[monitorID];
 | 
			
		||||
 | 
			
		||||
                if (monitor && ! monitor.active) {
 | 
			
		||||
                if (monitor && monitor.maintenance) {
 | 
			
		||||
                    result.maintenance++;
 | 
			
		||||
                }
 | 
			
		||||
                else if (monitor && ! monitor.active) {
 | 
			
		||||
                    result.pause++;
 | 
			
		||||
                } else if (beat) {
 | 
			
		||||
                    if (beat.status === 1) {
 | 
			
		||||
 
 | 
			
		||||
@@ -2,9 +2,22 @@
 | 
			
		||||
    <div class="container-fluid">
 | 
			
		||||
        <div class="row">
 | 
			
		||||
            <div v-if="! $root.isMobile" class="col-12 col-md-5 col-xl-4">
 | 
			
		||||
                <div>
 | 
			
		||||
                    <router-link to="/add" class="btn btn-primary mb-3"><font-awesome-icon icon="plus" /> {{ $t("Add New Monitor") }}</router-link>
 | 
			
		||||
                    <router-link to="/addMaintenance" class="btn btn-primary mb-3 float-end"><font-awesome-icon icon="wrench" /> {{ $t("Add New Maintenance") }}</router-link>
 | 
			
		||||
                <div class="dropdown dropdown-create">
 | 
			
		||||
                    <button class="btn btn-primary mb-3 dropdown-toggle" type="button" data-bs-toggle="dropdown">
 | 
			
		||||
                        <font-awesome-icon icon="plus" /> {{ $t("Create") }}
 | 
			
		||||
                    </button>
 | 
			
		||||
                    <ul class="dropdown-menu dropdown-menu-end">
 | 
			
		||||
                        <li>
 | 
			
		||||
                            <button type="button" class="dropdown-item" @click="this.$router.push('/add')">
 | 
			
		||||
                                <font-awesome-icon icon="heartbeat" /> {{ $t("Monitor") }}
 | 
			
		||||
                            </button>
 | 
			
		||||
                        </li>
 | 
			
		||||
                        <li>
 | 
			
		||||
                            <button type="button" class="dropdown-item" @click="this.$router.push('/addMaintenance')">
 | 
			
		||||
                                <font-awesome-icon icon="exclamation-circle" /> {{ $t("Maintenance") }}
 | 
			
		||||
                            </button>
 | 
			
		||||
                        </li>
 | 
			
		||||
                    </ul>
 | 
			
		||||
                </div>
 | 
			
		||||
                <MonitorList :scrollbar="true" />
 | 
			
		||||
            </div>
 | 
			
		||||
 
 | 
			
		||||
@@ -17,7 +17,7 @@
 | 
			
		||||
                    </div>
 | 
			
		||||
                    <div class="col">
 | 
			
		||||
                        <h3>{{ $t("Maintenance") }}</h3>
 | 
			
		||||
                        <span class="num text-maintenance">{{ stats.maintenance }}</span>
 | 
			
		||||
                        <span class="num text-maintenance">{{ $root.stats.maintenance }}</span>
 | 
			
		||||
                    </div>
 | 
			
		||||
                    <div class="col">
 | 
			
		||||
                        <h3>{{ $t("Unknown") }}</h3>
 | 
			
		||||
 
 | 
			
		||||
@@ -606,7 +606,7 @@ export default {
 | 
			
		||||
                        toast.success(res.msg);
 | 
			
		||||
                        this.processing = false;
 | 
			
		||||
                        this.$root.getMonitorList();
 | 
			
		||||
                        this.$router.push("/dashboard/monitor/" + res.monitorID);
 | 
			
		||||
                        this.$router.push("/dashboard/" + res.monitorID);
 | 
			
		||||
                    } else {
 | 
			
		||||
                        toast.error(res.msg);
 | 
			
		||||
                        this.processing = false;
 | 
			
		||||
 
 | 
			
		||||
@@ -195,16 +195,20 @@
 | 
			
		||||
            </div>
 | 
			
		||||
 | 
			
		||||
            <!-- Maintenance -->
 | 
			
		||||
            <div v-if="maintenance.length !== 0" v-for="maintenanceItem in maintenance" class="shadow-box alert mb-4 p-4 maintenance" role="alert" :class="maintenanceClass">
 | 
			
		||||
                <h4 v-text="maintenanceItem.title" class="alert-heading" />
 | 
			
		||||
            <template v-if="maintenance.length !== 0">
 | 
			
		||||
                <div v-for="maintenanceItem in maintenance" class="shadow-box alert mb-4 p-4 maintenance" role="alert"
 | 
			
		||||
                     :class="maintenanceClass">
 | 
			
		||||
                    <h4 v-text="maintenanceItem.title" class="alert-heading"/>
 | 
			
		||||
 | 
			
		||||
                <div v-text="maintenanceItem.description" class="content" />
 | 
			
		||||
                    <div v-text="maintenanceItem.description" class="content"/>
 | 
			
		||||
 | 
			
		||||
                <!-- Incident Date -->
 | 
			
		||||
                <div class="date mt-3">
 | 
			
		||||
                    {{ $t("End") }}: {{ $root.datetimeMaintenance(maintenanceItem.end_date) }} ({{ dateFromNow(maintenanceItem.start_date) }})<br />
 | 
			
		||||
                    <!-- Incident Date -->
 | 
			
		||||
                    <div class="date mt-3">
 | 
			
		||||
                        {{ $t("End") }}: {{ $root.datetimeMaintenance(maintenanceItem.end_date) }}
 | 
			
		||||
                        ({{ dateFromNow(maintenanceItem.start_date) }})<br/>
 | 
			
		||||
                    </div>
 | 
			
		||||
                </div>
 | 
			
		||||
            </div>
 | 
			
		||||
            </template>
 | 
			
		||||
 | 
			
		||||
            <!-- Overall Status -->
 | 
			
		||||
            <div class="shadow-box list  p-4 overall-status mb-4">
 | 
			
		||||
@@ -300,7 +304,7 @@
 | 
			
		||||
import axios from "axios";
 | 
			
		||||
import PublicGroupList from "../components/PublicGroupList.vue";
 | 
			
		||||
import ImageCropUpload from "vue-image-crop-upload";
 | 
			
		||||
import { STATUS_PAGE_ALL_DOWN, STATUS_PAGE_ALL_UP, STATUS_PAGE_MAINTENANCE, STATUS_PAGE_PARTIAL_DOWN, UP } from "../util.ts";
 | 
			
		||||
import { STATUS_PAGE_ALL_DOWN, STATUS_PAGE_ALL_UP, STATUS_PAGE_MAINTENANCE, STATUS_PAGE_PARTIAL_DOWN, UP, MAINTENANCE } from "../util.ts";
 | 
			
		||||
import { useToast } from "vue-toastification";
 | 
			
		||||
import dayjs from "dayjs";
 | 
			
		||||
import Favico from "favico.js";
 | 
			
		||||
@@ -579,14 +583,10 @@ export default {
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            this.incident = res.data.incident;
 | 
			
		||||
            this.maintenance = res.data.maintenance;
 | 
			
		||||
            this.$root.publicGroupList = res.data.publicGroupList;
 | 
			
		||||
        });
 | 
			
		||||
 | 
			
		||||
        //TODO: make OK with multi status pages
 | 
			
		||||
        axios.get("/api/status-page/maintenance-list").then((res) => {
 | 
			
		||||
            this.maintenance = res.data;
 | 
			
		||||
        });
 | 
			
		||||
 | 
			
		||||
        // 5mins a loop
 | 
			
		||||
        this.updateHeartbeatList();
 | 
			
		||||
        feedInterval = setInterval(() => {
 | 
			
		||||
 
 | 
			
		||||
@@ -280,7 +280,7 @@ export function genSecret(length = 64) {
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
export function getMonitorRelativeURL(id: string) {
 | 
			
		||||
    return "/dashboard/monitor/" + id;
 | 
			
		||||
    return "/dashboard/" + id;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
export function getMaintenanceRelativeURL(id: string) {
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user