mirror of
				https://github.com/louislam/uptime-kuma.git
				synced 2025-11-04 21:56:12 +08:00 
			
		
		
		
	[new status page] wip
This commit is contained in:
		@@ -10,7 +10,9 @@ CREATE TABLE [status_page](
 | 
				
			|||||||
    [published] BOOLEAN NOT NULL DEFAULT 1,
 | 
					    [published] BOOLEAN NOT NULL DEFAULT 1,
 | 
				
			||||||
    [search_engine_index] BOOLEAN NOT NULL DEFAULT 1,
 | 
					    [search_engine_index] BOOLEAN NOT NULL DEFAULT 1,
 | 
				
			||||||
    [show_tags] BOOLEAN NOT NULL DEFAULT 0,
 | 
					    [show_tags] BOOLEAN NOT NULL DEFAULT 0,
 | 
				
			||||||
    [password] VARCHAR
 | 
					    [password] VARCHAR,
 | 
				
			||||||
 | 
					    [date_created] DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,
 | 
				
			||||||
 | 
					    [date_modified] DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP
 | 
				
			||||||
);
 | 
					);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
CREATE UNIQUE INDEX [slug] ON [status_page]([slug]);
 | 
					CREATE UNIQUE INDEX [slug] ON [status_page]([slug]);
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										44
									
								
								server/model/status_page.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										44
									
								
								server/model/status_page.js
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,44 @@
 | 
				
			|||||||
 | 
					const { BeanModel } = require("redbean-node/dist/bean-model");
 | 
				
			||||||
 | 
					const { R } = require("redbean-node");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					class StatusPage extends BeanModel {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    static async sendStatusPageList(io, socket) {
 | 
				
			||||||
 | 
					        let result = {};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        let list = await R.findAll("status_page", " ORDER BY title ");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        for (let item of list) {
 | 
				
			||||||
 | 
					            result[item.id] = await item.toJSON();
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        io.to(socket.userID).emit("statusPageList", result);
 | 
				
			||||||
 | 
					        return list;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    async toJSON() {
 | 
				
			||||||
 | 
					        return {
 | 
				
			||||||
 | 
					            id: this.id,
 | 
				
			||||||
 | 
					            slug: this.slug,
 | 
				
			||||||
 | 
					            title: this.title,
 | 
				
			||||||
 | 
					            icon: this.icon,
 | 
				
			||||||
 | 
					            theme: this.theme,
 | 
				
			||||||
 | 
					            published: !!this.published,
 | 
				
			||||||
 | 
					            showTags: !!this.show_tags,
 | 
				
			||||||
 | 
					        };
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    async toPublicJSON() {
 | 
				
			||||||
 | 
					        return {
 | 
				
			||||||
 | 
					            slug: this.slug,
 | 
				
			||||||
 | 
					            title: this.title,
 | 
				
			||||||
 | 
					            icon: this.icon,
 | 
				
			||||||
 | 
					            theme: this.theme,
 | 
				
			||||||
 | 
					            published: !!this.published,
 | 
				
			||||||
 | 
					            showTags: !!this.show_tags,
 | 
				
			||||||
 | 
					        };
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					module.exports = StatusPage;
 | 
				
			||||||
@@ -83,33 +83,28 @@ router.get("/api/push/:pushToken", async (request, response) => {
 | 
				
			|||||||
});
 | 
					});
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// Status Page Config
 | 
					// Status Page Config
 | 
				
			||||||
router.get("/api/status-page/config", async (_request, response) => {
 | 
					router.get("/api/status-page/config/:slug", async (request, response) => {
 | 
				
			||||||
    allowDevAllOrigin(response);
 | 
					    allowDevAllOrigin(response);
 | 
				
			||||||
 | 
					    let slug = request.params.slug;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    let config = await getSettings("statusPage");
 | 
					    let statusPage = await R.findOne("status_page", " slug = ? ", [
 | 
				
			||||||
 | 
					        slug
 | 
				
			||||||
 | 
					    ]);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    if (! config.statusPageTheme) {
 | 
					    if (!statusPage) {
 | 
				
			||||||
        config.statusPageTheme = "light";
 | 
					        response.statusCode = 404;
 | 
				
			||||||
 | 
					        response.json({
 | 
				
			||||||
 | 
					            msg: "Not Found"
 | 
				
			||||||
 | 
					        });
 | 
				
			||||||
 | 
					        return;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    if (! config.statusPagePublished) {
 | 
					    response.json(await statusPage.toPublicJSON());
 | 
				
			||||||
        config.statusPagePublished = true;
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    if (! config.statusPageTags) {
 | 
					 | 
				
			||||||
        config.statusPageTags = false;
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    if (! config.title) {
 | 
					 | 
				
			||||||
        config.title = "Uptime Kuma";
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    response.json(config);
 | 
					 | 
				
			||||||
});
 | 
					});
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// Status Page - Get the current Incident
 | 
					// Status Page - Get the current Incident
 | 
				
			||||||
// Can fetch only if published
 | 
					// Can fetch only if published
 | 
				
			||||||
router.get("/api/status-page/incident", async (_, response) => {
 | 
					router.get("/api/status-page/incident/:slug", async (_, response) => {
 | 
				
			||||||
    allowDevAllOrigin(response);
 | 
					    allowDevAllOrigin(response);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    try {
 | 
					    try {
 | 
				
			||||||
@@ -133,7 +128,7 @@ router.get("/api/status-page/incident", async (_, response) => {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
// Status Page - Monitor List
 | 
					// Status Page - Monitor List
 | 
				
			||||||
// Can fetch only if published
 | 
					// Can fetch only if published
 | 
				
			||||||
router.get("/api/status-page/monitor-list", cache("5 minutes"), async (_request, response) => {
 | 
					router.get("/api/status-page/monitor-list/:slug", cache("5 minutes"), async (_request, response) => {
 | 
				
			||||||
    allowDevAllOrigin(response);
 | 
					    allowDevAllOrigin(response);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    try {
 | 
					    try {
 | 
				
			||||||
@@ -172,7 +167,7 @@ router.get("/api/status-page/monitor-list", cache("5 minutes"), async (_request,
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
// Status Page Polling Data
 | 
					// Status Page Polling Data
 | 
				
			||||||
// Can fetch only if published
 | 
					// Can fetch only if published
 | 
				
			||||||
router.get("/api/status-page/heartbeat", cache("5 minutes"), async (_request, response) => {
 | 
					router.get("/api/status-page/heartbeat/:slug", cache("5 minutes"), async (_request, response) => {
 | 
				
			||||||
    allowDevAllOrigin(response);
 | 
					    allowDevAllOrigin(response);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    try {
 | 
					    try {
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -132,6 +132,7 @@ const { sendNotificationList, sendHeartbeatList, sendImportantHeartbeatList, sen
 | 
				
			|||||||
const { statusPageSocketHandler } = require("./socket-handlers/status-page-socket-handler");
 | 
					const { statusPageSocketHandler } = require("./socket-handlers/status-page-socket-handler");
 | 
				
			||||||
const databaseSocketHandler = require("./socket-handlers/database-socket-handler");
 | 
					const databaseSocketHandler = require("./socket-handlers/database-socket-handler");
 | 
				
			||||||
const TwoFA = require("./2fa");
 | 
					const TwoFA = require("./2fa");
 | 
				
			||||||
 | 
					const StatusPage = require("./model/status_page");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
app.use(express.json());
 | 
					app.use(express.json());
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -1414,6 +1415,8 @@ async function afterLogin(socket, user) {
 | 
				
			|||||||
    for (let monitorID in monitorList) {
 | 
					    for (let monitorID in monitorList) {
 | 
				
			||||||
        await Monitor.sendStats(io, monitorID, user.id);
 | 
					        await Monitor.sendStats(io, monitorID, user.id);
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    await StatusPage.sendStatusPageList(io, socket);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
async function getMonitorJSONList(userID) {
 | 
					async function getMonitorJSONList(userID) {
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -92,6 +92,10 @@ textarea.form-control {
 | 
				
			|||||||
    }
 | 
					    }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					.btn-dark {
 | 
				
			||||||
 | 
					    background-color: #161B22;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@media (max-width: 550px) {
 | 
					@media (max-width: 550px) {
 | 
				
			||||||
    .table-shadow-box {
 | 
					    .table-shadow-box {
 | 
				
			||||||
        padding: 10px !important;
 | 
					        padding: 10px !important;
 | 
				
			||||||
@@ -162,12 +166,12 @@ textarea.form-control {
 | 
				
			|||||||
    .form-check-input:checked {
 | 
					    .form-check-input:checked {
 | 
				
			||||||
        border-color: $primary; // Re-apply bootstrap border
 | 
					        border-color: $primary; // Re-apply bootstrap border
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
    
 | 
					
 | 
				
			||||||
    .form-switch .form-check-input {
 | 
					    .form-switch .form-check-input {
 | 
				
			||||||
        background-color: #232f3b;
 | 
					        background-color: #232f3b;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    a,
 | 
					    a:not(.btn),
 | 
				
			||||||
    .table,
 | 
					    .table,
 | 
				
			||||||
    .nav-link {
 | 
					    .nav-link {
 | 
				
			||||||
        color: $dark-font-color;
 | 
					        color: $dark-font-color;
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -34,6 +34,8 @@ import {
 | 
				
			|||||||
    faAward,
 | 
					    faAward,
 | 
				
			||||||
    faLink,
 | 
					    faLink,
 | 
				
			||||||
    faChevronDown,
 | 
					    faChevronDown,
 | 
				
			||||||
 | 
					    faPen,
 | 
				
			||||||
 | 
					    faExternalLinkSquareAlt,
 | 
				
			||||||
} from "@fortawesome/free-solid-svg-icons";
 | 
					} from "@fortawesome/free-solid-svg-icons";
 | 
				
			||||||
 | 
					
 | 
				
			||||||
library.add(
 | 
					library.add(
 | 
				
			||||||
@@ -67,6 +69,8 @@ library.add(
 | 
				
			|||||||
    faAward,
 | 
					    faAward,
 | 
				
			||||||
    faLink,
 | 
					    faLink,
 | 
				
			||||||
    faChevronDown,
 | 
					    faChevronDown,
 | 
				
			||||||
 | 
					    faPen,
 | 
				
			||||||
 | 
					    faExternalLinkSquareAlt,
 | 
				
			||||||
);
 | 
					);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
export { FontAwesomeIcon };
 | 
					export { FontAwesomeIcon };
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -183,7 +183,7 @@ export default {
 | 
				
			|||||||
    "Edit Status Page": "Edit Status Page",
 | 
					    "Edit Status Page": "Edit Status Page",
 | 
				
			||||||
    "Go to Dashboard": "Go to Dashboard",
 | 
					    "Go to Dashboard": "Go to Dashboard",
 | 
				
			||||||
    "Status Page": "Status Page",
 | 
					    "Status Page": "Status Page",
 | 
				
			||||||
    "Status Pages": "Status Page",
 | 
					    "Status Pages": "Status Pages",
 | 
				
			||||||
    defaultNotificationName: "My {notification} Alert ({number})",
 | 
					    defaultNotificationName: "My {notification} Alert ({number})",
 | 
				
			||||||
    here: "here",
 | 
					    here: "here",
 | 
				
			||||||
    Required: "Required",
 | 
					    Required: "Required",
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -19,9 +19,9 @@
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
            <ul class="nav nav-pills">
 | 
					            <ul class="nav nav-pills">
 | 
				
			||||||
                <li class="nav-item me-2">
 | 
					                <li class="nav-item me-2">
 | 
				
			||||||
                    <a href="/status" class="nav-link status-page">
 | 
					                    <router-link to="/manage-status-page" class="nav-link">
 | 
				
			||||||
                        <font-awesome-icon icon="stream" /> {{ $t("Status Page") }}
 | 
					                        <font-awesome-icon icon="stream" /> {{ $t("Status Pages") }}
 | 
				
			||||||
                    </a>
 | 
					                    </router-link>
 | 
				
			||||||
                </li>
 | 
					                </li>
 | 
				
			||||||
                <li v-if="$root.loggedIn" class="nav-item me-2">
 | 
					                <li v-if="$root.loggedIn" class="nav-item me-2">
 | 
				
			||||||
                    <router-link to="/dashboard" class="nav-link">
 | 
					                    <router-link to="/dashboard" class="nav-link">
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -33,6 +33,7 @@ export default {
 | 
				
			|||||||
            uptimeList: { },
 | 
					            uptimeList: { },
 | 
				
			||||||
            tlsInfoList: {},
 | 
					            tlsInfoList: {},
 | 
				
			||||||
            notificationList: [],
 | 
					            notificationList: [],
 | 
				
			||||||
 | 
					            statusPageList: [],
 | 
				
			||||||
            connectionErrorMsg: "Cannot connect to the socket server. Reconnecting...",
 | 
					            connectionErrorMsg: "Cannot connect to the socket server. Reconnecting...",
 | 
				
			||||||
        };
 | 
					        };
 | 
				
			||||||
    },
 | 
					    },
 | 
				
			||||||
@@ -103,6 +104,11 @@ export default {
 | 
				
			|||||||
                this.notificationList = data;
 | 
					                this.notificationList = data;
 | 
				
			||||||
            });
 | 
					            });
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            socket.on("statusPageList", (data) => {
 | 
				
			||||||
 | 
					                console.log(data);
 | 
				
			||||||
 | 
					                this.statusPageList = data;
 | 
				
			||||||
 | 
					            });
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            socket.on("heartbeat", (data) => {
 | 
					            socket.on("heartbeat", (data) => {
 | 
				
			||||||
                if (! (data.monitorID in this.heartbeatList)) {
 | 
					                if (! (data.monitorID in this.heartbeatList)) {
 | 
				
			||||||
                    this.heartbeatList[data.monitorID] = [];
 | 
					                    this.heartbeatList[data.monitorID] = [];
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										104
									
								
								src/pages/ManageStatusPage.vue
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										104
									
								
								src/pages/ManageStatusPage.vue
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,104 @@
 | 
				
			|||||||
 | 
					<template>
 | 
				
			||||||
 | 
					    <transition name="slide-fade" appear>
 | 
				
			||||||
 | 
					        <div>
 | 
				
			||||||
 | 
					            <h1 class="mb-3">
 | 
				
			||||||
 | 
					                {{ $t("Status Pages") }}
 | 
				
			||||||
 | 
					            </h1>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            <div>
 | 
				
			||||||
 | 
					                <router-link to="/add-status-page" class="btn btn-primary mb-3"><font-awesome-icon icon="plus" /> {{ $t("Add New Status Page") }}</router-link>
 | 
				
			||||||
 | 
					            </div>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            <div class="shadow-box">
 | 
				
			||||||
 | 
					                <div v-for="statusPage in $root.statusPageList" class="item">
 | 
				
			||||||
 | 
					                    <div class="row">
 | 
				
			||||||
 | 
					                        <div class="col">
 | 
				
			||||||
 | 
					                            <div class="title">{{ statusPage.title }}</div>
 | 
				
			||||||
 | 
					                            <div class="slug">/status/{{ statusPage.slug }}</div>
 | 
				
			||||||
 | 
					                        </div>
 | 
				
			||||||
 | 
					                        <div class="col-lg-6 col-xl-5">
 | 
				
			||||||
 | 
					                            <div class="btn-group">
 | 
				
			||||||
 | 
					                                <a target="_blank" :href="'/status/' + statusPage.slug" class="btn btn-dark">
 | 
				
			||||||
 | 
					                                    <font-awesome-icon icon="external-link-square-alt" /><br />
 | 
				
			||||||
 | 
					                                    {{ $t("Manage") }}
 | 
				
			||||||
 | 
					                                </a>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                                <router-link to="/" class="btn btn-danger">
 | 
				
			||||||
 | 
					                                    <font-awesome-icon icon="trash" /><br />
 | 
				
			||||||
 | 
					                                    {{ $t("Delete") }}
 | 
				
			||||||
 | 
					                                </router-link>
 | 
				
			||||||
 | 
					                            </div>
 | 
				
			||||||
 | 
					                        </div>
 | 
				
			||||||
 | 
					                    </div>
 | 
				
			||||||
 | 
					                </div>
 | 
				
			||||||
 | 
					            </div>
 | 
				
			||||||
 | 
					        </div>
 | 
				
			||||||
 | 
					    </transition>
 | 
				
			||||||
 | 
					</template>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					<script>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					export default {
 | 
				
			||||||
 | 
					    components: {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    },
 | 
				
			||||||
 | 
					    data() {
 | 
				
			||||||
 | 
					        return {
 | 
				
			||||||
 | 
					        };
 | 
				
			||||||
 | 
					    },
 | 
				
			||||||
 | 
					    computed: {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    },
 | 
				
			||||||
 | 
					    mounted() {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    },
 | 
				
			||||||
 | 
					    methods: {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    },
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					</script>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					<style lang="scss" scoped>
 | 
				
			||||||
 | 
					    @import "../assets/vars.scss";
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    .item {
 | 
				
			||||||
 | 
					        display: block;
 | 
				
			||||||
 | 
					        text-decoration: none;
 | 
				
			||||||
 | 
					        padding: 13px 15px 10px 15px;
 | 
				
			||||||
 | 
					        border-radius: 10px;
 | 
				
			||||||
 | 
					        transition: all ease-in-out 0.15s;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        &:hover {
 | 
				
			||||||
 | 
					            background-color: $highlight-white;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        &.active {
 | 
				
			||||||
 | 
					            background-color: #cdf8f4;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        .title {
 | 
				
			||||||
 | 
					            font-weight: bold;
 | 
				
			||||||
 | 
					            font-size: 20px;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        .slug {
 | 
				
			||||||
 | 
					            font-size: 14px;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        .btn-group {
 | 
				
			||||||
 | 
					            //margin-top: 7px;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    .dark {
 | 
				
			||||||
 | 
					        .item {
 | 
				
			||||||
 | 
					            &:hover {
 | 
				
			||||||
 | 
					                background-color: $dark-bg2;
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            &.active {
 | 
				
			||||||
 | 
					                background-color: $dark-bg2;
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					</style>
 | 
				
			||||||
@@ -167,6 +167,8 @@ footer {
 | 
				
			|||||||
        margin: 0.5em;
 | 
					        margin: 0.5em;
 | 
				
			||||||
        padding: 0.7em 1em;
 | 
					        padding: 0.7em 1em;
 | 
				
			||||||
        cursor: pointer;
 | 
					        cursor: pointer;
 | 
				
			||||||
 | 
					        border-left-width: 0;
 | 
				
			||||||
 | 
					        transition: all ease-in-out 0.1s;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    .menu-item:hover {
 | 
					    .menu-item:hover {
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -247,6 +247,7 @@ export default {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
    data() {
 | 
					    data() {
 | 
				
			||||||
        return {
 | 
					        return {
 | 
				
			||||||
 | 
					            slug: null,
 | 
				
			||||||
            enableEditMode: false,
 | 
					            enableEditMode: false,
 | 
				
			||||||
            enableEditIncidentMode: false,
 | 
					            enableEditIncidentMode: false,
 | 
				
			||||||
            hasToken: false,
 | 
					            hasToken: false,
 | 
				
			||||||
@@ -296,15 +297,15 @@ export default {
 | 
				
			|||||||
        },
 | 
					        },
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        isPublished() {
 | 
					        isPublished() {
 | 
				
			||||||
            return this.config.statusPagePublished;
 | 
					            return this.config.published;
 | 
				
			||||||
        },
 | 
					        },
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        theme() {
 | 
					        theme() {
 | 
				
			||||||
            return this.config.statusPageTheme;
 | 
					            return this.config.theme;
 | 
				
			||||||
        },
 | 
					        },
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        tagsVisible() {
 | 
					        tagsVisible() {
 | 
				
			||||||
            return this.config.statusPageTags
 | 
					            return this.config.showTags;
 | 
				
			||||||
        },
 | 
					        },
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        logoClass() {
 | 
					        logoClass() {
 | 
				
			||||||
@@ -378,8 +379,8 @@ export default {
 | 
				
			|||||||
        },
 | 
					        },
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        // Set Theme
 | 
					        // Set Theme
 | 
				
			||||||
        "config.statusPageTheme"() {
 | 
					        "config.theme"() {
 | 
				
			||||||
            this.$root.statusPageTheme = this.config.statusPageTheme;
 | 
					            this.$root.statusPageTheme = this.config.theme;
 | 
				
			||||||
            this.loadedTheme = true;
 | 
					            this.loadedTheme = true;
 | 
				
			||||||
        },
 | 
					        },
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -409,7 +410,13 @@ export default {
 | 
				
			|||||||
        }
 | 
					        }
 | 
				
			||||||
    },
 | 
					    },
 | 
				
			||||||
    async mounted() {
 | 
					    async mounted() {
 | 
				
			||||||
        axios.get("/api/status-page/config").then((res) => {
 | 
					        this.slug = this.$route.params.slug;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        if (!this.slug) {
 | 
				
			||||||
 | 
					            this.slug = "default";
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        axios.get("/api/status-page/config/" + this.slug).then((res) => {
 | 
				
			||||||
            this.config = res.data;
 | 
					            this.config = res.data;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            if (this.config.logo) {
 | 
					            if (this.config.logo) {
 | 
				
			||||||
@@ -417,13 +424,13 @@ export default {
 | 
				
			|||||||
            }
 | 
					            }
 | 
				
			||||||
        });
 | 
					        });
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        axios.get("/api/status-page/incident").then((res) => {
 | 
					        axios.get("/api/status-page/incident/" + this.slug).then((res) => {
 | 
				
			||||||
            if (res.data.ok) {
 | 
					            if (res.data.ok) {
 | 
				
			||||||
                this.incident = res.data.incident;
 | 
					                this.incident = res.data.incident;
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
        });
 | 
					        });
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        axios.get("/api/status-page/monitor-list").then((res) => {
 | 
					        axios.get("/api/status-page/monitor-list/" + this.slug).then((res) => {
 | 
				
			||||||
            this.$root.publicGroupList = res.data;
 | 
					            this.$root.publicGroupList = res.data;
 | 
				
			||||||
        });
 | 
					        });
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -438,7 +445,7 @@ export default {
 | 
				
			|||||||
        updateHeartbeatList() {
 | 
					        updateHeartbeatList() {
 | 
				
			||||||
            // If editMode, it will use the data from websocket.
 | 
					            // If editMode, it will use the data from websocket.
 | 
				
			||||||
            if (! this.editMode) {
 | 
					            if (! this.editMode) {
 | 
				
			||||||
                axios.get("/api/status-page/heartbeat").then((res) => {
 | 
					                axios.get("/api/status-page/heartbeat/" + this.slug).then((res) => {
 | 
				
			||||||
                    this.$root.heartbeatList = res.data.heartbeatList;
 | 
					                    this.$root.heartbeatList = res.data.heartbeatList;
 | 
				
			||||||
                    this.$root.uptimeList = res.data.uptimeList;
 | 
					                    this.$root.uptimeList = res.data.uptimeList;
 | 
				
			||||||
                    this.loadedData = true;
 | 
					                    this.loadedData = true;
 | 
				
			||||||
@@ -485,10 +492,10 @@ export default {
 | 
				
			|||||||
        },
 | 
					        },
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        changeTheme(name) {
 | 
					        changeTheme(name) {
 | 
				
			||||||
            this.config.statusPageTheme = name;
 | 
					            this.config.theme = name;
 | 
				
			||||||
        },
 | 
					        },
 | 
				
			||||||
        changeTagsVisibilty(newState) {
 | 
					        changeTagsVisibilty(newState) {
 | 
				
			||||||
            this.config.statusPageTags = newState;
 | 
					            this.config.showTags = newState;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            // On load, the status page will not include tags if it's not enabled for security reasons
 | 
					            // On load, the status page will not include tags if it's not enabled for security reasons
 | 
				
			||||||
            // Which means if we enable tags, it won't show in the UI until saved
 | 
					            // Which means if we enable tags, it won't show in the UI until saved
 | 
				
			||||||
@@ -501,9 +508,9 @@ export default {
 | 
				
			|||||||
                        return {
 | 
					                        return {
 | 
				
			||||||
                            ...monitor,
 | 
					                            ...monitor,
 | 
				
			||||||
                            tags: newState ? this.$root.monitorList[monitor.id].tags : []
 | 
					                            tags: newState ? this.$root.monitorList[monitor.id].tags : []
 | 
				
			||||||
                        }
 | 
					                        };
 | 
				
			||||||
                    })
 | 
					                    })
 | 
				
			||||||
                }
 | 
					                };
 | 
				
			||||||
            });
 | 
					            });
 | 
				
			||||||
        },
 | 
					        },
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -18,6 +18,7 @@ import MonitorHistory from "./components/settings/MonitorHistory.vue";
 | 
				
			|||||||
import Security from "./components/settings/Security.vue";
 | 
					import Security from "./components/settings/Security.vue";
 | 
				
			||||||
import Backup from "./components/settings/Backup.vue";
 | 
					import Backup from "./components/settings/Backup.vue";
 | 
				
			||||||
import About from "./components/settings/About.vue";
 | 
					import About from "./components/settings/About.vue";
 | 
				
			||||||
 | 
					import ManageStatusPage from "./pages/ManageStatusPage.vue";
 | 
				
			||||||
 | 
					
 | 
				
			||||||
const routes = [
 | 
					const routes = [
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
@@ -98,6 +99,10 @@ const routes = [
 | 
				
			|||||||
                            },
 | 
					                            },
 | 
				
			||||||
                        ]
 | 
					                        ]
 | 
				
			||||||
                    },
 | 
					                    },
 | 
				
			||||||
 | 
					                    {
 | 
				
			||||||
 | 
					                        path: "/manage-status-page",
 | 
				
			||||||
 | 
					                        component: ManageStatusPage,
 | 
				
			||||||
 | 
					                    },
 | 
				
			||||||
                ],
 | 
					                ],
 | 
				
			||||||
            },
 | 
					            },
 | 
				
			||||||
        ],
 | 
					        ],
 | 
				
			||||||
@@ -114,6 +119,10 @@ const routes = [
 | 
				
			|||||||
        path: "/status",
 | 
					        path: "/status",
 | 
				
			||||||
        component: StatusPage,
 | 
					        component: StatusPage,
 | 
				
			||||||
    },
 | 
					    },
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        path: "/status/:slug",
 | 
				
			||||||
 | 
					        component: StatusPage,
 | 
				
			||||||
 | 
					    },
 | 
				
			||||||
];
 | 
					];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
export const router = createRouter({
 | 
					export const router = createRouter({
 | 
				
			||||||
 
 | 
				
			|||||||
		Reference in New Issue
	
	Block a user