Update status page's maintenance message

This commit is contained in:
Louis Lam 2022-10-11 20:56:48 +08:00
parent e07aa982c3
commit dfb75c8afb
6 changed files with 80 additions and 81 deletions

View file

@ -91,7 +91,7 @@ class StatusPage extends BeanModel {
incident = incident.toPublicJSON(); incident = incident.toPublicJSON();
} }
let maintenance = await StatusPage.getMaintenanceList(statusPage.id); let maintenanceList = await StatusPage.getMaintenanceList(statusPage.id);
// Public Group List // Public Group List
const publicGroupList = []; const publicGroupList = [];
@ -111,7 +111,7 @@ class StatusPage extends BeanModel {
config: await statusPage.toPublicJSON(), config: await statusPage.toPublicJSON(),
incident, incident,
publicGroupList, publicGroupList,
maintenance, maintenanceList,
}; };
} }
@ -281,13 +281,13 @@ class StatusPage extends BeanModel {
let activeCondition = Maintenance.getActiveMaintenanceSQLCondition(); let activeCondition = Maintenance.getActiveMaintenanceSQLCondition();
let maintenanceBeanList = R.convertToBeans("maintenance", await R.getAll(` let maintenanceBeanList = R.convertToBeans("maintenance", await R.getAll(`
SELECT m.* SELECT maintenance.*
FROM maintenance m, maintenance_status_page msp, maintenance_timeslot FROM maintenance, maintenance_status_page msp, maintenance_timeslot
WHERE msp.maintenance_id = m.id WHERE msp.maintenance_id = maintenance.id
AND maintenance_timeslot.maintenance.id = m.id AND maintenance_timeslot.maintenance_id = maintenance.id
AND msp.status_page_id = ? AND msp.status_page_id = ?
AND ${activeCondition} AND ${activeCondition}
ORDER BY m.end_date ORDER BY maintenance.end_date
`, [ statusPageId ])); `, [ statusPageId ]));
for (const bean of maintenanceBeanList) { for (const bean of maintenanceBeanList) {

View file

@ -0,0 +1,44 @@
<template>
<div class="timeslot">
<div v-if="maintenance.strategy === 'manual'">
{{ $t("Manual") }}
</div>
<div v-else-if="maintenance.timeslotList.length > 0">
{{ maintenance.timeslotList[0].startDateServerTimezone }}
<span class="to">-</span>
{{ maintenance.timeslotList[0].endDateServerTimezone }}
(UTC{{ maintenance.timeslotList[0].serverTimezoneOffset }})
</div>
</div>
</template>
<script>
export default {
props: {
maintenance: {
type: Object,
required: true
},
},
};
</script>
<style lang="scss">
.timeslot {
margin-top: 5px;
display: inline-block;
font-size: 14px;
background-color: rgba(255, 255, 255, 0.5);
border-radius: 20px;
padding: 0 10px;
.to {
margin: 0 6px;
}
.dark & {
color: white;
background-color: rgba(255, 255, 255, 0.1);
}
}
</style>

View file

@ -20,13 +20,10 @@ export default {
"Selected status pages": "Selected status pages", "Selected status pages": "Selected status pages",
"Select status pages...": "Select status pages...", "Select status pages...": "Select status pages...",
recurringIntervalMessage: "Run once every day | Run once every {0} days", recurringIntervalMessage: "Run once every day | Run once every {0} days",
"End": "End",
affectedMonitorsDescription: "Select monitors that are affected by current maintenance", affectedMonitorsDescription: "Select monitors that are affected by current maintenance",
affectedStatusPages: "Show this maintenance message on selected status pages", affectedStatusPages: "Show this maintenance message on selected status pages",
atLeastOneMonitor: "Select at least one affected monitor", atLeastOneMonitor: "Select at least one affected monitor",
maintenanceInvalidDate: "Invalid maintenance end date entered",
selectedStatusPagesDescription: "Select status pages to display maintenance info on", selectedStatusPagesDescription: "Select status pages to display maintenance info on",
atLeastOneStatusPage: "Select at least one status page",
maintenanceTitleExample: "Network infrastructure maintenance", maintenanceTitleExample: "Network infrastructure maintenance",
maintenanceDescriptionExample: "Example: Network infrastructure maintenance is underway which will affect some of our services.", maintenanceDescriptionExample: "Example: Network infrastructure maintenance is underway which will affect some of our services.",
passwordNotMatchMsg: "The repeat password does not match.", passwordNotMatchMsg: "The repeat password does not match.",
@ -637,4 +634,7 @@ export default {
"maintenanceStatus-scheduled": "Scheduled", "maintenanceStatus-scheduled": "Scheduled",
"maintenanceStatus-ended": "Ended", "maintenanceStatus-ended": "Ended",
"maintenanceStatus-unknown": "Unknown", "maintenanceStatus-unknown": "Unknown",
"Display Timezone": "Display Timezone",
"Server Timezone": "Server Timezone",
statusPageMaintenanceEndDate: "End",
}; };

View file

@ -422,22 +422,6 @@ export default {
return this.processing = false; return this.processing = false;
} }
/*
TODO: Temporary disable
if (this.maintenance.start_date >= this.maintenance.end_date) {
toast.error(this.$t("maintenanceInvalidDate"));
return this.processing = false;
}
if (!this.showOnAllPages && this.selectedStatusPages.length === 0) {
toast.error(this.$t("atLeastOneStatusPage"));
return this.processing = false;
}
this.maintenance.start_date = this.$root.toUTC(this.maintenance.start_date);
this.maintenance.end_date = this.$root.toUTC(this.maintenance.end_date);
*/
if (this.isAdd) { if (this.isAdd) {
this.$root.addMaintenance(this.maintenance, async (res) => { this.$root.addMaintenance(this.maintenance, async (res) => {
if (res.ok) { if (res.ok) {

View file

@ -33,13 +33,7 @@
{{ $t("maintenanceStatus-" + item.status) }} {{ $t("maintenanceStatus-" + item.status) }}
</div> </div>
<div v-if="item.strategy === 'manual'" class="timeslot"> <MaintenanceTime :maintenance="item" />
{{ $t("Manual") }}
</div>
<div v-else-if="item.timeslotList.length > 0" class="timeslot">
{{ item.timeslotList[0].startDateServerTimezone }} <span class="to">-</span> {{ item.timeslotList[0].endDateServerTimezone }}
(UTC{{ item.timeslotList[0].serverTimezoneOffset }})
</div>
</div> </div>
</div> </div>
@ -86,11 +80,13 @@
import { getResBaseURL } from "../util-frontend"; import { getResBaseURL } from "../util-frontend";
import { getMaintenanceRelativeURL } from "../util.ts"; import { getMaintenanceRelativeURL } from "../util.ts";
import Confirm from "../components/Confirm.vue"; import Confirm from "../components/Confirm.vue";
import MaintenanceTime from "../components/MaintenanceTime.vue";
import { useToast } from "vue-toastification"; import { useToast } from "vue-toastification";
const toast = useToast(); const toast = useToast();
export default { export default {
components: { components: {
MaintenanceTime,
Confirm, Confirm,
}, },
data() { data() {
@ -265,24 +261,6 @@ export default {
.status { .status {
font-size: 14px; font-size: 14px;
} }
.timeslot {
margin-top: 5px;
display: inline-block;
font-size: 14px;
background-color: rgba(255, 255, 255, 0.5);
border-radius: 20px;
padding: 0 10px;
.to {
margin: 0 6px;
}
.dark & {
color: white;
background-color: rgba(255, 255, 255, 0.1);
}
}
} }
} }

View file

@ -195,33 +195,6 @@
</div> </div>
</div> </div>
<!-- Maintenance -->
<template v-if="maintenance.length">
<div
v-for="maintenanceItem in maintenance" :key="maintenanceItem.id"
class="shadow-box alert mb-4 p-3 bg-maintenance mt-4 position-relative" role="alert"
>
<div class="item">
<div class="row">
<div class="col-1 col-md-1 d-flex justify-content-center align-items-center">
<font-awesome-icon
icon="wrench"
class="maintenance-icon"
/>
</div>
<div class="col-11 col-md-11">
<h4 class="alert-heading">{{ maintenanceItem.title }}</h4>
<div class="content">{{ maintenanceItem.description }}</div>
<div class="date mt-3">
{{ $t("End") }}: {{ $root.datetimeMaintenance(maintenanceItem.end_date) }}
</div>
</div>
</div>
</div>
</div>
</template>
<!-- Overall Status --> <!-- Overall Status -->
<div class="shadow-box list p-4 overall-status mb-4"> <div class="shadow-box list p-4 overall-status mb-4">
<div v-if="Object.keys($root.publicMonitorList).length === 0 && loadedData"> <div v-if="Object.keys($root.publicMonitorList).length === 0 && loadedData">
@ -247,7 +220,7 @@
<div v-else-if="isMaintenance"> <div v-else-if="isMaintenance">
<font-awesome-icon icon="wrench" class="status-maintenance" /> <font-awesome-icon icon="wrench" class="status-maintenance" />
{{ $t("Maintenance") }} {{ $t("maintenanceStatus-under-maintenance") }}
</div> </div>
<div v-else> <div v-else>
@ -256,6 +229,18 @@
</template> </template>
</div> </div>
<!-- Maintenance -->
<template v-if="maintenanceList.length > 0">
<div
v-for="maintenance in maintenanceList" :key="maintenance.id"
class="shadow-box alert mb-4 p-3 bg-maintenance mt-4 position-relative" role="alert"
>
<h4 class="alert-heading">{{ maintenance.title }}</h4>
<div class="content">{{ maintenance.description }}</div>
<MaintenanceTime :maintenance="maintenance" />
</div>
</template>
<!-- Description --> <!-- Description -->
<strong v-if="editMode">{{ $t("Description") }}:</strong> <strong v-if="editMode">{{ $t("Description") }}:</strong>
<Editable v-model="config.description" :contenteditable="editMode" tag="div" class="mb-4 description" /> <Editable v-model="config.description" :contenteditable="editMode" tag="div" class="mb-4 description" />
@ -327,6 +312,7 @@ import "vue-prism-editor/dist/prismeditor.min.css"; // import the styles somewhe
import { useToast } from "vue-toastification"; import { useToast } from "vue-toastification";
import Confirm from "../components/Confirm.vue"; import Confirm from "../components/Confirm.vue";
import PublicGroupList from "../components/PublicGroupList.vue"; import PublicGroupList from "../components/PublicGroupList.vue";
import MaintenanceTime from "../components/MaintenanceTime.vue";
import { getResBaseURL } from "../util-frontend"; import { getResBaseURL } from "../util-frontend";
import { STATUS_PAGE_ALL_DOWN, STATUS_PAGE_ALL_UP, STATUS_PAGE_MAINTENANCE, STATUS_PAGE_PARTIAL_DOWN, UP, MAINTENANCE } from "../util.ts"; import { STATUS_PAGE_ALL_DOWN, STATUS_PAGE_ALL_UP, STATUS_PAGE_MAINTENANCE, STATUS_PAGE_PARTIAL_DOWN, UP, MAINTENANCE } from "../util.ts";
@ -348,6 +334,7 @@ export default {
ImageCropUpload, ImageCropUpload,
Confirm, Confirm,
PrismEditor, PrismEditor,
MaintenanceTime,
}, },
// Leave Page for vue route change // Leave Page for vue route change
@ -388,7 +375,7 @@ export default {
loadedData: false, loadedData: false,
baseURL: "", baseURL: "",
clickedEditButton: false, clickedEditButton: false,
maintenance: [], maintenanceList: [],
}; };
}, },
computed: { computed: {
@ -594,7 +581,7 @@ export default {
} }
this.incident = res.data.incident; this.incident = res.data.incident;
this.maintenance = res.data.maintenance; this.maintenanceList = res.data.maintenanceList;
this.$root.publicGroupList = res.data.publicGroupList; this.$root.publicGroupList = res.data.publicGroupList;
}).catch( function (error) { }).catch( function (error) {
if (error.response.status === 404) { if (error.response.status === 404) {
@ -1069,4 +1056,10 @@ footer {
} }
} }
.bg-maintenance {
.alert-heading {
font-weight: bold;
}
}
</style> </style>