mirror of
				https://github.com/louislam/uptime-kuma.git
				synced 2025-11-04 13:46:13 +08:00 
			
		
		
		
	Update status page's maintenance message
This commit is contained in:
		@@ -91,7 +91,7 @@ class StatusPage extends BeanModel {
 | 
			
		||||
            incident = incident.toPublicJSON();
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        let maintenance = await StatusPage.getMaintenanceList(statusPage.id);
 | 
			
		||||
        let maintenanceList = await StatusPage.getMaintenanceList(statusPage.id);
 | 
			
		||||
 | 
			
		||||
        // Public Group List
 | 
			
		||||
        const publicGroupList = [];
 | 
			
		||||
@@ -111,7 +111,7 @@ class StatusPage extends BeanModel {
 | 
			
		||||
            config: await statusPage.toPublicJSON(),
 | 
			
		||||
            incident,
 | 
			
		||||
            publicGroupList,
 | 
			
		||||
            maintenance,
 | 
			
		||||
            maintenanceList,
 | 
			
		||||
        };
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
@@ -281,13 +281,13 @@ class StatusPage extends BeanModel {
 | 
			
		||||
 | 
			
		||||
            let activeCondition = Maintenance.getActiveMaintenanceSQLCondition();
 | 
			
		||||
            let maintenanceBeanList = R.convertToBeans("maintenance", await R.getAll(`
 | 
			
		||||
                SELECT m.*
 | 
			
		||||
                FROM maintenance m, maintenance_status_page msp, maintenance_timeslot
 | 
			
		||||
                WHERE  msp.maintenance_id = m.id
 | 
			
		||||
                    AND maintenance_timeslot.maintenance.id = m.id
 | 
			
		||||
                SELECT maintenance.*
 | 
			
		||||
                FROM maintenance, maintenance_status_page msp, maintenance_timeslot
 | 
			
		||||
                WHERE msp.maintenance_id = maintenance.id
 | 
			
		||||
                    AND maintenance_timeslot.maintenance_id = maintenance.id
 | 
			
		||||
                    AND msp.status_page_id = ?
 | 
			
		||||
                    AND ${activeCondition}
 | 
			
		||||
                ORDER BY m.end_date
 | 
			
		||||
                ORDER BY maintenance.end_date
 | 
			
		||||
            `, [ statusPageId ]));
 | 
			
		||||
 | 
			
		||||
            for (const bean of maintenanceBeanList) {
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										44
									
								
								src/components/MaintenanceTime.vue
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										44
									
								
								src/components/MaintenanceTime.vue
									
									
									
									
									
										Normal 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>
 | 
			
		||||
@@ -20,13 +20,10 @@ export default {
 | 
			
		||||
    "Selected status pages": "Selected status pages",
 | 
			
		||||
    "Select status pages...": "Select status pages...",
 | 
			
		||||
    recurringIntervalMessage: "Run once every day | Run once every {0} days",
 | 
			
		||||
    "End": "End",
 | 
			
		||||
    affectedMonitorsDescription: "Select monitors that are affected by current maintenance",
 | 
			
		||||
    affectedStatusPages: "Show this maintenance message on selected status pages",
 | 
			
		||||
    atLeastOneMonitor: "Select at least one affected monitor",
 | 
			
		||||
    maintenanceInvalidDate: "Invalid maintenance end date entered",
 | 
			
		||||
    selectedStatusPagesDescription: "Select status pages to display maintenance info on",
 | 
			
		||||
    atLeastOneStatusPage: "Select at least one status page",
 | 
			
		||||
    maintenanceTitleExample: "Network infrastructure maintenance",
 | 
			
		||||
    maintenanceDescriptionExample: "Example: Network infrastructure maintenance is underway which will affect some of our services.",
 | 
			
		||||
    passwordNotMatchMsg: "The repeat password does not match.",
 | 
			
		||||
@@ -637,4 +634,7 @@ export default {
 | 
			
		||||
    "maintenanceStatus-scheduled": "Scheduled",
 | 
			
		||||
    "maintenanceStatus-ended": "Ended",
 | 
			
		||||
    "maintenanceStatus-unknown": "Unknown",
 | 
			
		||||
    "Display Timezone": "Display Timezone",
 | 
			
		||||
    "Server Timezone": "Server Timezone",
 | 
			
		||||
    statusPageMaintenanceEndDate: "End",
 | 
			
		||||
};
 | 
			
		||||
 
 | 
			
		||||
@@ -422,22 +422,6 @@ export default {
 | 
			
		||||
                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) {
 | 
			
		||||
                this.$root.addMaintenance(this.maintenance, async (res) => {
 | 
			
		||||
                    if (res.ok) {
 | 
			
		||||
 
 | 
			
		||||
@@ -33,13 +33,7 @@
 | 
			
		||||
                                {{ $t("maintenanceStatus-" + item.status) }}
 | 
			
		||||
                            </div>
 | 
			
		||||
 | 
			
		||||
                            <div v-if="item.strategy === 'manual'" class="timeslot">
 | 
			
		||||
                                {{ $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>
 | 
			
		||||
                            <MaintenanceTime :maintenance="item" />
 | 
			
		||||
                        </div>
 | 
			
		||||
                    </div>
 | 
			
		||||
 | 
			
		||||
@@ -86,11 +80,13 @@
 | 
			
		||||
import { getResBaseURL } from "../util-frontend";
 | 
			
		||||
import { getMaintenanceRelativeURL } from "../util.ts";
 | 
			
		||||
import Confirm from "../components/Confirm.vue";
 | 
			
		||||
import MaintenanceTime from "../components/MaintenanceTime.vue";
 | 
			
		||||
import { useToast } from "vue-toastification";
 | 
			
		||||
const toast = useToast();
 | 
			
		||||
 | 
			
		||||
export default {
 | 
			
		||||
    components: {
 | 
			
		||||
        MaintenanceTime,
 | 
			
		||||
        Confirm,
 | 
			
		||||
    },
 | 
			
		||||
    data() {
 | 
			
		||||
@@ -265,24 +261,6 @@ export default {
 | 
			
		||||
                .status {
 | 
			
		||||
                    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);
 | 
			
		||||
                    }
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -195,33 +195,6 @@
 | 
			
		||||
                </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 -->
 | 
			
		||||
            <div class="shadow-box list  p-4 overall-status mb-4">
 | 
			
		||||
                <div v-if="Object.keys($root.publicMonitorList).length === 0 && loadedData">
 | 
			
		||||
@@ -247,7 +220,7 @@
 | 
			
		||||
 | 
			
		||||
                    <div v-else-if="isMaintenance">
 | 
			
		||||
                        <font-awesome-icon icon="wrench" class="status-maintenance" />
 | 
			
		||||
                        {{ $t("Maintenance") }}
 | 
			
		||||
                        {{ $t("maintenanceStatus-under-maintenance") }}
 | 
			
		||||
                    </div>
 | 
			
		||||
 | 
			
		||||
                    <div v-else>
 | 
			
		||||
@@ -256,6 +229,18 @@
 | 
			
		||||
                </template>
 | 
			
		||||
            </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 -->
 | 
			
		||||
            <strong v-if="editMode">{{ $t("Description") }}:</strong>
 | 
			
		||||
            <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 Confirm from "../components/Confirm.vue";
 | 
			
		||||
import PublicGroupList from "../components/PublicGroupList.vue";
 | 
			
		||||
import MaintenanceTime from "../components/MaintenanceTime.vue";
 | 
			
		||||
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";
 | 
			
		||||
 | 
			
		||||
@@ -348,6 +334,7 @@ export default {
 | 
			
		||||
        ImageCropUpload,
 | 
			
		||||
        Confirm,
 | 
			
		||||
        PrismEditor,
 | 
			
		||||
        MaintenanceTime,
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    // Leave Page for vue route change
 | 
			
		||||
@@ -388,7 +375,7 @@ export default {
 | 
			
		||||
            loadedData: false,
 | 
			
		||||
            baseURL: "",
 | 
			
		||||
            clickedEditButton: false,
 | 
			
		||||
            maintenance: [],
 | 
			
		||||
            maintenanceList: [],
 | 
			
		||||
        };
 | 
			
		||||
    },
 | 
			
		||||
    computed: {
 | 
			
		||||
@@ -594,7 +581,7 @@ export default {
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            this.incident = res.data.incident;
 | 
			
		||||
            this.maintenance = res.data.maintenance;
 | 
			
		||||
            this.maintenanceList = res.data.maintenanceList;
 | 
			
		||||
            this.$root.publicGroupList = res.data.publicGroupList;
 | 
			
		||||
        }).catch( function (error) {
 | 
			
		||||
            if (error.response.status === 404) {
 | 
			
		||||
@@ -1069,4 +1056,10 @@ footer {
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
.bg-maintenance {
 | 
			
		||||
    .alert-heading {
 | 
			
		||||
        font-weight: bold;
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
</style>
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user