diff --git a/server/socket-handlers/status-page-socket-handler.js b/server/socket-handlers/status-page-socket-handler.js index 7fe17560..74e4105d 100644 --- a/server/socket-handlers/status-page-socket-handler.js +++ b/server/socket-handlers/status-page-socket-handler.js @@ -6,6 +6,7 @@ const ImageDataURI = require("../image-data-uri"); const Database = require("../database"); const apicache = require("../modules/apicache"); const StatusPage = require("../model/status_page"); +const server = require("../server"); module.exports.statusPageSocketHandler = (socket) => { @@ -242,4 +243,51 @@ module.exports.statusPageSocketHandler = (socket) => { } }); + // Delete a status page + socket.on("deleteStatusPage", async (slug, callback) => { + try { + checkLogin(socket); + + let statusPageID = await StatusPage.slugToID(slug); + + if (statusPageID) { + + // Reset entry page if it is the default one. + if (server.entryPage === "statusPage-" + slug) { + server.entryPage = "dashboard"; + await setSettings("entryPage", server.entryPage, "general"); + } + + // No need to delete records from `status_page_cname`, because it has cascade foreign key. + // But for incident & group, it is hard to add cascade foreign key during migration, so they have to be deleted manually. + + // Delete incident + await R.exec("DELETE FROM incident WHERE status_page_id = ? ", [ + statusPageID + ]); + + // Delete group + await R.exec("DELETE FROM `group` WHERE status_page_id = ? ", [ + statusPageID + ]); + + // Delete status_page + await R.exec("DELETE FROM status_page WHERE id = ? ", [ + statusPageID + ]); + + } else { + throw new Error("Status Page is not found"); + } + + callback({ + ok: true, + }); + } catch (error) { + callback({ + ok: false, + msg: error.message, + }); + } + }); }; diff --git a/src/languages/en.js b/src/languages/en.js index d66d3188..0def91d0 100644 --- a/src/languages/en.js +++ b/src/languages/en.js @@ -331,21 +331,21 @@ export default { dark: "dark", Post: "Post", "Please input title and content": "Please input title and content", - Created: "Created", + "Created": "Created", "Last Updated": "Last Updated", - Unpin: "Unpin", + "Unpin": "Unpin", "Switch to Light Theme": "Switch to Light Theme", "Switch to Dark Theme": "Switch to Dark Theme", "Show Tags": "Show Tags", "Hide Tags": "Hide Tags", - Description: "Description", + "Description": "Description", "No monitors available.": "No monitors available.", "Add one": "Add one", "No Monitors": "No Monitors", "Untitled Group": "Untitled Group", - Services: "Services", - Discard: "Discard", - Cancel: "Cancel", + "Services": "Services", + "Discard": "Discard", + "Cancel": "Cancel", "Powered by": "Powered by", shrinkDatabaseDescription: "Trigger database VACUUM for SQLite. If your database is created after 1.10.0, AUTO_VACUUM is already enabled and this action is not needed.", serwersms: "SerwerSMS.pl", @@ -353,7 +353,7 @@ export default { serwersmsAPIPassword: "API Password", serwersmsPhoneNumber: "Phone number", serwersmsSenderName: "SMS Sender Name (registered via customer portal)", - "stackfield": "Stackfield", + stackfield: "Stackfield", smtpDkimSettings: "DKIM Settings", smtpDkimDesc: "Please refer to the Nodemailer DKIM {0} for usage.", documentation: "documentation", @@ -370,4 +370,5 @@ export default { alertaApiKey: "API Key", alertaAlertState: "Alert State", alertaRecoverState: "Recover State", + deleteStatusPageMsg: "Are you sure want to delete this status page?", }; diff --git a/src/languages/zh-HK.js b/src/languages/zh-HK.js index ba063155..4def65d3 100644 --- a/src/languages/zh-HK.js +++ b/src/languages/zh-HK.js @@ -96,7 +96,7 @@ export default { Test: "測試", keywordDescription: "搜索 HTML 或 JSON 裡是否有出現關鍵字(注意英文大細階)", "Certificate Info": "憑證詳細資料", - deleteMonitorMsg: "是否確定刪除這個監測器", + deleteMonitorMsg: "是否確定刪除這個監測器?", deleteNotificationMsg: "是否確定刪除這個通知設定?如監測器啟用了這個通知,將會收不到通知。", "Resolver Server": "DNS 伺服器", "Resource Record Type": "DNS 記錄類型", @@ -199,4 +199,5 @@ export default { pushbullet: "Pushbullet", line: "Line Messenger", mattermost: "Mattermost", + deleteStatusPageMsg: "是否確定刪除這個 Status Page?", }; diff --git a/src/pages/StatusPage.vue b/src/pages/StatusPage.vue index 9bafc8dc..3c7e3e95 100644 --- a/src/pages/StatusPage.vue +++ b/src/pages/StatusPage.vue @@ -40,10 +40,12 @@ - +
+ +
+ + + {{ $t("deleteStatusPageMsg") }} + @@ -240,6 +246,7 @@ import { useToast } from "vue-toastification"; import dayjs from "dayjs"; import Favico from "favico.js"; import { getResBaseURL } from "../util-frontend"; +import Confirm from "../components/Confirm.vue"; const toast = useToast(); @@ -254,7 +261,8 @@ const favicon = new Favico({ export default { components: { PublicGroupList, - ImageCropUpload + ImageCropUpload, + Confirm, }, // Leave Page for vue route change @@ -533,6 +541,21 @@ export default { }); }, + deleteDialog() { + this.$refs.confirmDelete.show(); + }, + + deleteStatusPage() { + this.$root.getSocket().emit("deleteStatusPage", this.slug, (res) => { + if (res.ok) { + this.enableEditMode = false; + location.href = "/manage-status-page"; + } else { + toast.error(res.msg); + } + }); + }, + monitorSelectorLabel(monitor) { return `${monitor.name}`; }, @@ -573,8 +596,6 @@ export default { }) }; }); - } else { - } }, @@ -705,6 +726,11 @@ h1 { overflow-y: auto; border-right: 1px solid #ededed; + .danger-zone { + border-top: 1px solid #ededed; + padding-top: 15px; + } + .sidebar-footer { width: 100%; bottom: 0; @@ -793,6 +819,10 @@ footer { background-color: $dark-header-bg; border-right-color: $dark-border-color; + .danger-zone { + border-top-color: $dark-border-color; + } + .sidebar-footer { border-top-color: $dark-border-color; }