mirror of
				https://github.com/louislam/uptime-kuma.git
				synced 2025-11-04 13:46:13 +08:00 
			
		
		
		
	Update Maintenance UI for recurring
This commit is contained in:
		
							
								
								
									
										25
									
								
								package-lock.json
									
									
									
										generated
									
									
									
								
							
							
						
						
									
										25
									
								
								package-lock.json
									
									
									
										generated
									
									
									
								
							@@ -68,6 +68,7 @@
 | 
			
		||||
                "@vitejs/plugin-legacy": "~2.1.0",
 | 
			
		||||
                "@vitejs/plugin-vue": "~3.1.0",
 | 
			
		||||
                "@vue/compiler-sfc": "~3.2.36",
 | 
			
		||||
                "@vuepic/vue-datepicker": "^3.4.8",
 | 
			
		||||
                "aedes": "^0.46.3",
 | 
			
		||||
                "babel-plugin-rewire": "~1.2.0",
 | 
			
		||||
                "bootstrap": "5.1.3",
 | 
			
		||||
@@ -3941,6 +3942,21 @@
 | 
			
		||||
            "integrity": "sha512-dTyhTIRmGXBjxJE+skC8tTWCGLCVc4wQgRRLt8+O9p5ewBAjoBwtCAkLPrtToSr1xltoe3st21Pv953aOZ7alg==",
 | 
			
		||||
            "dev": true
 | 
			
		||||
        },
 | 
			
		||||
        "node_modules/@vuepic/vue-datepicker": {
 | 
			
		||||
            "version": "3.4.8",
 | 
			
		||||
            "resolved": "https://registry.npmjs.org/@vuepic/vue-datepicker/-/vue-datepicker-3.4.8.tgz",
 | 
			
		||||
            "integrity": "sha512-nbuMA7IgjtT99LqcjSTSUcl7omTZSB+7vYSWQ9gQm31Frm/1wn54fT1Q0HaRD9nHXX982AACbqeND4K80SKONw==",
 | 
			
		||||
            "dev": true,
 | 
			
		||||
            "dependencies": {
 | 
			
		||||
                "date-fns": "^2.29.2"
 | 
			
		||||
            },
 | 
			
		||||
            "engines": {
 | 
			
		||||
                "node": ">=14"
 | 
			
		||||
            },
 | 
			
		||||
            "peerDependencies": {
 | 
			
		||||
                "vue": ">=3.2.0"
 | 
			
		||||
            }
 | 
			
		||||
        },
 | 
			
		||||
        "node_modules/abab": {
 | 
			
		||||
            "version": "2.0.6",
 | 
			
		||||
            "resolved": "https://registry.npmjs.org/abab/-/abab-2.0.6.tgz",
 | 
			
		||||
@@ -20409,6 +20425,15 @@
 | 
			
		||||
            "integrity": "sha512-dTyhTIRmGXBjxJE+skC8tTWCGLCVc4wQgRRLt8+O9p5ewBAjoBwtCAkLPrtToSr1xltoe3st21Pv953aOZ7alg==",
 | 
			
		||||
            "dev": true
 | 
			
		||||
        },
 | 
			
		||||
        "@vuepic/vue-datepicker": {
 | 
			
		||||
            "version": "3.4.8",
 | 
			
		||||
            "resolved": "https://registry.npmjs.org/@vuepic/vue-datepicker/-/vue-datepicker-3.4.8.tgz",
 | 
			
		||||
            "integrity": "sha512-nbuMA7IgjtT99LqcjSTSUcl7omTZSB+7vYSWQ9gQm31Frm/1wn54fT1Q0HaRD9nHXX982AACbqeND4K80SKONw==",
 | 
			
		||||
            "dev": true,
 | 
			
		||||
            "requires": {
 | 
			
		||||
                "date-fns": "^2.29.2"
 | 
			
		||||
            }
 | 
			
		||||
        },
 | 
			
		||||
        "abab": {
 | 
			
		||||
            "version": "2.0.6",
 | 
			
		||||
            "resolved": "https://registry.npmjs.org/abab/-/abab-2.0.6.tgz",
 | 
			
		||||
 
 | 
			
		||||
@@ -124,6 +124,7 @@
 | 
			
		||||
        "@vitejs/plugin-legacy": "~2.1.0",
 | 
			
		||||
        "@vitejs/plugin-vue": "~3.1.0",
 | 
			
		||||
        "@vue/compiler-sfc": "~3.2.36",
 | 
			
		||||
        "@vuepic/vue-datepicker": "^3.4.8",
 | 
			
		||||
        "aedes": "^0.46.3",
 | 
			
		||||
        "babel-plugin-rewire": "~1.2.0",
 | 
			
		||||
        "bootstrap": "5.1.3",
 | 
			
		||||
 
 | 
			
		||||
@@ -19,6 +19,8 @@ class Maintenance extends BeanModel {
 | 
			
		||||
            description: this.description,
 | 
			
		||||
            start_date: this.start_date,
 | 
			
		||||
            end_date: this.end_date,
 | 
			
		||||
            strategy: this.strategy,
 | 
			
		||||
            active: !!this.active,
 | 
			
		||||
        };
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
@@ -27,13 +29,7 @@ class Maintenance extends BeanModel {
 | 
			
		||||
     * @returns {Object}
 | 
			
		||||
     */
 | 
			
		||||
    async toJSON() {
 | 
			
		||||
        return {
 | 
			
		||||
            id: this.id,
 | 
			
		||||
            title: this.title,
 | 
			
		||||
            description: this.description,
 | 
			
		||||
            start_date: this.start_date,
 | 
			
		||||
            end_date: this.end_date,
 | 
			
		||||
        };
 | 
			
		||||
        return this.toPublicJSON();
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										39
									
								
								src/assets/vue-datepicker.scss
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										39
									
								
								src/assets/vue-datepicker.scss
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,39 @@
 | 
			
		||||
@import "@vuepic/vue-datepicker/dist/main.css";
 | 
			
		||||
@import "vars.scss";
 | 
			
		||||
 | 
			
		||||
// Must use #{ }
 | 
			
		||||
// Remark: https://stackoverflow.com/questions/50202991/unable-to-set-scss-variable-to-css-variable
 | 
			
		||||
.dp__theme_dark {
 | 
			
		||||
    --dp-background-color: #{$dark-bg2};
 | 
			
		||||
    --dp-text-color: #{$dark-font-color};
 | 
			
		||||
    --dp-hover-color: #484848;
 | 
			
		||||
    --dp-hover-text-color: #ffffff;
 | 
			
		||||
    --dp-hover-icon-color: #959595;
 | 
			
		||||
    --dp-primary-color: #{#5cdd8b};
 | 
			
		||||
    --dp-primary-text-color: #ffffff;
 | 
			
		||||
    --dp-secondary-color: #494949;
 | 
			
		||||
    --dp-border-color: #{$dark-border-color};
 | 
			
		||||
    --dp-menu-border-color: #2d2d2d;
 | 
			
		||||
    --dp-border-color-hover: #{$dark-border-color};
 | 
			
		||||
    --dp-disabled-color: #212121;
 | 
			
		||||
    --dp-scroll-bar-background: #212121;
 | 
			
		||||
    --dp-scroll-bar-color: #484848;
 | 
			
		||||
    --dp-success-color: #{$primary};
 | 
			
		||||
    --dp-success-color-disabled: #428f59;
 | 
			
		||||
    --dp-icon-color: #959595;
 | 
			
		||||
    --dp-danger-color: #e53935;
 | 
			
		||||
    --dp-highlight-color: rgba(0, 92, 178, 0.2);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
.dp__input {
 | 
			
		||||
    border-radius: $border-radius;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Fix: Full width of text input when using "inline textInput inlineWithInput" mode
 | 
			
		||||
.dp__main > div[aria-label="Datepicker input"] {
 | 
			
		||||
    width: 100%;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
.dp__main > div[aria-label="Datepicker menu"]:nth-child(2) {
 | 
			
		||||
    margin-top: 20px;
 | 
			
		||||
}
 | 
			
		||||
@@ -18,7 +18,8 @@ export default {
 | 
			
		||||
    "All Status Pages": "All Status Pages",
 | 
			
		||||
    "Selected status pages": "Selected status pages",
 | 
			
		||||
    "Select status pages...": "Select status pages...",
 | 
			
		||||
    End: "End",
 | 
			
		||||
    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",
 | 
			
		||||
@@ -61,9 +62,7 @@ export default {
 | 
			
		||||
    List: "List",
 | 
			
		||||
    Add: "Add",
 | 
			
		||||
    "Add Monitor": "Add Monitor",
 | 
			
		||||
    "Add Maintenance": "Add Maintenance",
 | 
			
		||||
    "Add New Monitor": "Add New Monitor",
 | 
			
		||||
    "Add New Maintenance": "Add New Maintenance",
 | 
			
		||||
    "Quick Stats": "Quick Stats",
 | 
			
		||||
    Up: "Up",
 | 
			
		||||
    Down: "Down",
 | 
			
		||||
@@ -605,4 +604,21 @@ export default {
 | 
			
		||||
    goAlert: "GoAlert",
 | 
			
		||||
    backupOutdatedWarning: "Deprecated: Since a lot of features added and this backup feature is a bit unmaintained, it cannot generate or restore a complete backup.",
 | 
			
		||||
    backupRecommend: "Please backup the volume or the data folder (./data/) directly instead.",
 | 
			
		||||
    recurringInterval: "Interval",
 | 
			
		||||
    "Recurring": "Recurring",
 | 
			
		||||
    strategyManual: "Active/Inactive Manually",
 | 
			
		||||
    warningTimezone: "It is NOT your current browser's timezone. It is your server's timezone.",
 | 
			
		||||
    weekdayShortMon: "Mon",
 | 
			
		||||
    weekdayShortTue: "Tue",
 | 
			
		||||
    weekdayShortWed: "Wed",
 | 
			
		||||
    weekdayShortThu: "Thu",
 | 
			
		||||
    weekdayShortFri: "Fri",
 | 
			
		||||
    weekdayShortSat: "Sat",
 | 
			
		||||
    weekdayShortSun: "Sun",
 | 
			
		||||
    dayOfMonth: "Day of Month",
 | 
			
		||||
    lastDay: "Last Day",
 | 
			
		||||
    lastDay1: "Last Day of Month",
 | 
			
		||||
    lastDay2: "2nd Last Day of Month",
 | 
			
		||||
    lastDay3: "3rd Last Day of Month",
 | 
			
		||||
    lastDay4: "4th Last Day of Month",
 | 
			
		||||
};
 | 
			
		||||
 
 | 
			
		||||
@@ -5,6 +5,7 @@ import Toast from "vue-toastification";
 | 
			
		||||
import "vue-toastification/dist/index.css";
 | 
			
		||||
import App from "./App.vue";
 | 
			
		||||
import "./assets/app.scss";
 | 
			
		||||
import "./assets/vue-datepicker.scss";
 | 
			
		||||
import { i18n } from "./i18n";
 | 
			
		||||
import { FontAwesomeIcon } from "./icon.js";
 | 
			
		||||
import datetime from "./mixins/datetime";
 | 
			
		||||
 
 | 
			
		||||
@@ -26,6 +26,15 @@ export default {
 | 
			
		||||
            return dayjs.tz(value, this.timezone).utc().format();
 | 
			
		||||
        },
 | 
			
		||||
 | 
			
		||||
        /**
 | 
			
		||||
         * Used for <input type="datetime" />
 | 
			
		||||
         * @param value
 | 
			
		||||
         * @returns {string}
 | 
			
		||||
         */
 | 
			
		||||
        toDateTimeInputFormat(value) {
 | 
			
		||||
            return this.datetimeFormat(value, "YYYY-MM-DDTHH:mm");
 | 
			
		||||
        },
 | 
			
		||||
 | 
			
		||||
        /**
 | 
			
		||||
         * Return a given value in the format YYYY-MM-DD HH:mm:ss
 | 
			
		||||
         * @param {any} value Value to format as date time
 | 
			
		||||
 
 | 
			
		||||
@@ -46,6 +46,10 @@ export default {
 | 
			
		||||
                }
 | 
			
		||||
                return this.userTheme;
 | 
			
		||||
            }
 | 
			
		||||
        },
 | 
			
		||||
 | 
			
		||||
        isDark() {
 | 
			
		||||
            return this.theme === "dark";
 | 
			
		||||
        }
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -7,7 +7,7 @@
 | 
			
		||||
                    <div class="row">
 | 
			
		||||
                        <div class="col-xl-7">
 | 
			
		||||
                            <!-- Title -->
 | 
			
		||||
                            <div class="my-3">
 | 
			
		||||
                            <div class="mb-3">
 | 
			
		||||
                                <label for="name" class="form-label">{{ $t("Title") }}</label>
 | 
			
		||||
                                <input
 | 
			
		||||
                                    id="name" v-model="maintenance.title" type="text" class="form-control"
 | 
			
		||||
@@ -35,7 +35,6 @@
 | 
			
		||||
                                    track-by="id"
 | 
			
		||||
                                    label="name"
 | 
			
		||||
                                    :multiple="true"
 | 
			
		||||
                                    :allow-empty="false"
 | 
			
		||||
                                    :close-on-select="false"
 | 
			
		||||
                                    :clear-on-select="false"
 | 
			
		||||
                                    :preserve-search="true"
 | 
			
		||||
@@ -70,7 +69,6 @@
 | 
			
		||||
                                        track-by="id"
 | 
			
		||||
                                        label="name"
 | 
			
		||||
                                        :multiple="true"
 | 
			
		||||
                                        :allow-empty="true"
 | 
			
		||||
                                        :close-on-select="false"
 | 
			
		||||
                                        :clear-on-select="false"
 | 
			
		||||
                                        :preserve-search="true"
 | 
			
		||||
@@ -82,25 +80,131 @@
 | 
			
		||||
                                </div>
 | 
			
		||||
                            </div>
 | 
			
		||||
 | 
			
		||||
                            <h2 class="mt-5">{{ $t("Effective Date Range") }}</h2>
 | 
			
		||||
                            <h2 class="mt-5">{{ $t("Date and Time") }}</h2>
 | 
			
		||||
 | 
			
		||||
                            <!-- Start Date Time -->
 | 
			
		||||
                            <div>⚠️ {{ $t("warningTimezone") }}</div>
 | 
			
		||||
 | 
			
		||||
                            <!-- Strategy -->
 | 
			
		||||
                            <div class="my-3">
 | 
			
		||||
                                <label for="start_date" class="form-label">{{ $t("Start Date") }}</label>
 | 
			
		||||
                                <input
 | 
			
		||||
                                    id="start_date" v-model="maintenance.start_date" :type="'datetime-local'"
 | 
			
		||||
                                    class="form-control" :class="{'dark-calendar': dark }" required
 | 
			
		||||
                                >
 | 
			
		||||
                                <label for="strategy" class="form-label">{{ $t("Strategy") }}</label>
 | 
			
		||||
                                <select id="strategy" v-model="maintenance.strategy" class="form-select">
 | 
			
		||||
                                    <option value="manual">{{ $t("strategyManual") }}</option>
 | 
			
		||||
                                    <option value="single">Single Maintenance Window</option>
 | 
			
		||||
                                    <option value="recurring-interval">{{ $t("Recurring") }} - {{ $t("recurringInterval") }}</option>
 | 
			
		||||
                                    <option value="recurring-weekday">{{ $t("Recurring") }} - Weekday</option>
 | 
			
		||||
                                    <option value="recurring-day-of-month">{{ $t("Recurring") }} - Day of Month</option>
 | 
			
		||||
                                    <option v-if="false" value="recurring-day-of-year">{{ $t("Recurring") }} - Day of Year</option>
 | 
			
		||||
                                </select>
 | 
			
		||||
                            </div>
 | 
			
		||||
 | 
			
		||||
                            <!-- End Date Time -->
 | 
			
		||||
                            <div class="my-3">
 | 
			
		||||
                                <label for="end_date" class="form-label">{{ $t("End Date") }}</label>
 | 
			
		||||
                                <input
 | 
			
		||||
                                    id="end_date" v-model="maintenance.end_date" :type="'datetime-local'"
 | 
			
		||||
                                    class="form-control" :class="{'dark-calendar': dark }" required
 | 
			
		||||
                                >
 | 
			
		||||
                            </div>
 | 
			
		||||
                            <!-- Single Maintenance Window -->
 | 
			
		||||
                            <template v-if="maintenance.strategy === 'single'">
 | 
			
		||||
                                <!-- DateTime Range -->
 | 
			
		||||
                                <div class="my-3">
 | 
			
		||||
                                    <label class="form-label">{{ $t("DateTime Range") }}</label>
 | 
			
		||||
                                    <Datepicker
 | 
			
		||||
                                        v-model="maintenance.dateTimeRange"
 | 
			
		||||
                                        :dark="$root.isDark"
 | 
			
		||||
                                        range textInput
 | 
			
		||||
                                        :monthChangeOnScroll="false"
 | 
			
		||||
                                        :minDate="minDate"
 | 
			
		||||
                                        format="yyyy-MM-dd HH:mm"
 | 
			
		||||
                                        utc="preserve"
 | 
			
		||||
                                    />
 | 
			
		||||
                                </div>
 | 
			
		||||
                            </template>
 | 
			
		||||
 | 
			
		||||
                            <!-- Recurring - Interval -->
 | 
			
		||||
                            <template v-if="maintenance.strategy === 'recurring-interval'">
 | 
			
		||||
                                <div class="my-3">
 | 
			
		||||
                                    <label for="interval-day" class="form-label">
 | 
			
		||||
                                        {{ $t("recurringInterval") }}
 | 
			
		||||
 | 
			
		||||
                                        <template v-if="maintenance.intervalDay >= 1">
 | 
			
		||||
                                            ({{
 | 
			
		||||
                                                $tc("recurringIntervalMessage", maintenance.intervalDay, [
 | 
			
		||||
                                                    maintenance.intervalDay
 | 
			
		||||
                                                ])
 | 
			
		||||
                                            }})
 | 
			
		||||
                                        </template>
 | 
			
		||||
                                    </label>
 | 
			
		||||
                                    <input id="interval-day" v-model="maintenance.intervalDay" type="number" class="form-control" required min="1" max="3650" step="1">
 | 
			
		||||
                                </div>
 | 
			
		||||
                            </template>
 | 
			
		||||
 | 
			
		||||
                            <!-- Recurring - Weekday -->
 | 
			
		||||
                            <template v-if="maintenance.strategy === 'recurring-weekday'">
 | 
			
		||||
                                <div class="my-3">
 | 
			
		||||
                                    <label for="interval-day" class="form-label">
 | 
			
		||||
                                        {{ $t("Weekday") }}
 | 
			
		||||
                                    </label>
 | 
			
		||||
 | 
			
		||||
                                    <!-- Weekday Picker -->
 | 
			
		||||
                                    <div class="weekday-picker">
 | 
			
		||||
                                        <div v-for="(weekday, index) in weekdays" :key="index">
 | 
			
		||||
                                            <label class="form-check-label" :for="weekday.id">{{ $t(weekday.langKey) }}</label>
 | 
			
		||||
                                            <div class="form-check-inline"><input :id="weekday.id" v-model="maintenance.weekdays" type="checkbox" :value="weekday.value" class="form-check-input"></div>
 | 
			
		||||
                                        </div>
 | 
			
		||||
                                    </div>
 | 
			
		||||
                                </div>
 | 
			
		||||
                            </template>
 | 
			
		||||
 | 
			
		||||
                            <!-- Recurring - Day of month -->
 | 
			
		||||
                            <template v-if="maintenance.strategy === 'recurring-day-of-month'">
 | 
			
		||||
                                <div class="my-3">
 | 
			
		||||
                                    <label for="interval-day" class="form-label">
 | 
			
		||||
                                        {{ $t("dayOfMonth") }}
 | 
			
		||||
                                    </label>
 | 
			
		||||
 | 
			
		||||
                                    <!-- Day Picker -->
 | 
			
		||||
                                    <div class="day-picker">
 | 
			
		||||
                                        <div v-for="index in 31" :key="index">
 | 
			
		||||
                                            <label class="form-check-label" :for="'day' + index">{{ index }}</label>
 | 
			
		||||
                                            <div class="form-check-inline">
 | 
			
		||||
                                                <input :id="'day' + index" v-model="maintenance.daysOfMonth" type="checkbox" :value="index" class="form-check-input">
 | 
			
		||||
                                            </div>
 | 
			
		||||
                                        </div>
 | 
			
		||||
                                    </div>
 | 
			
		||||
 | 
			
		||||
                                    <div class="mt-3 mb-2">{{ $t("lastDay") }}</div>
 | 
			
		||||
 | 
			
		||||
                                    <div v-for="(lastDay, index) in lastDays" :key="index" class="form-check">
 | 
			
		||||
                                        <input :id="lastDay.langKey" v-model="maintenance.daysOfMonth" type="checkbox" :value="lastDay.value" class="form-check-input">
 | 
			
		||||
                                        <label class="form-check-label" :for="lastDay.langKey">
 | 
			
		||||
                                            {{ $t(lastDay.langKey) }}
 | 
			
		||||
                                        </label>
 | 
			
		||||
                                    </div>
 | 
			
		||||
                                </div>
 | 
			
		||||
                            </template>
 | 
			
		||||
 | 
			
		||||
                            <!-- For any recurring types -->
 | 
			
		||||
                            <template v-if="maintenance.strategy === 'recurring-interval' || maintenance.strategy === 'recurring-weekday' || maintenance.strategy === 'recurring-day-of-month'">
 | 
			
		||||
                                <!-- Maintenance Time Window of a Day -->
 | 
			
		||||
                                <div class="my-3">
 | 
			
		||||
                                    <label class="form-label">{{ $t("Maintenance Time Window of a Day") }}</label>
 | 
			
		||||
                                    <Datepicker
 | 
			
		||||
                                        v-model="maintenance.timeRange"
 | 
			
		||||
                                        :dark="$root.isDark"
 | 
			
		||||
                                        timePicker disableTimeRangeValidation range
 | 
			
		||||
                                        placeholder="Select Time"
 | 
			
		||||
                                        textInput
 | 
			
		||||
                                    />
 | 
			
		||||
                                </div>
 | 
			
		||||
 | 
			
		||||
                                <!-- Date Range -->
 | 
			
		||||
                                <div class="my-3">
 | 
			
		||||
                                    <label class="form-label">{{ $t("Effective Date Range") }}</label>
 | 
			
		||||
                                    <Datepicker
 | 
			
		||||
                                        v-model="maintenance.dateRange"
 | 
			
		||||
                                        :dark="$root.isDark"
 | 
			
		||||
                                        range textInput datePicker
 | 
			
		||||
                                        :monthChangeOnScroll="false"
 | 
			
		||||
                                        :minDate="minDate"
 | 
			
		||||
                                        :enableTimePicker="false"
 | 
			
		||||
                                        utc="preserve"
 | 
			
		||||
                                    />
 | 
			
		||||
                                </div>
 | 
			
		||||
                            </template>
 | 
			
		||||
 | 
			
		||||
                            <div class="mt-4 mb-1">
 | 
			
		||||
                                <button
 | 
			
		||||
@@ -122,12 +226,15 @@
 | 
			
		||||
 | 
			
		||||
import { useToast } from "vue-toastification";
 | 
			
		||||
import VueMultiselect from "vue-multiselect";
 | 
			
		||||
import dayjs from "dayjs";
 | 
			
		||||
import Datepicker from "@vuepic/vue-datepicker";
 | 
			
		||||
 | 
			
		||||
const toast = useToast();
 | 
			
		||||
 | 
			
		||||
export default {
 | 
			
		||||
    components: {
 | 
			
		||||
        VueMultiselect,
 | 
			
		||||
        Datepicker
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    data() {
 | 
			
		||||
@@ -139,6 +246,63 @@ export default {
 | 
			
		||||
            showOnAllPages: false,
 | 
			
		||||
            selectedStatusPages: [],
 | 
			
		||||
            dark: (this.$root.theme === "dark"),
 | 
			
		||||
            neverEnd: false,
 | 
			
		||||
            minDate: this.$root.date(dayjs()) + " 00:00",
 | 
			
		||||
            lastDays: [
 | 
			
		||||
                {
 | 
			
		||||
                    langKey: "lastDay1",
 | 
			
		||||
                    value: "lastDay1",
 | 
			
		||||
                },
 | 
			
		||||
                {
 | 
			
		||||
                    langKey: "lastDay2",
 | 
			
		||||
                    value: "lastDay2",
 | 
			
		||||
                },
 | 
			
		||||
                {
 | 
			
		||||
                    langKey: "lastDay3",
 | 
			
		||||
                    value: "lastDay3",
 | 
			
		||||
                },
 | 
			
		||||
                {
 | 
			
		||||
                    langKey: "lastDay4",
 | 
			
		||||
                    value: "lastDay4",
 | 
			
		||||
                }
 | 
			
		||||
            ],
 | 
			
		||||
            weekdays: [
 | 
			
		||||
                {
 | 
			
		||||
                    id: "weekday1",
 | 
			
		||||
                    langKey: "weekdayShortMon",
 | 
			
		||||
                    value: 1,
 | 
			
		||||
                },
 | 
			
		||||
                {
 | 
			
		||||
                    id: "weekday2",
 | 
			
		||||
                    langKey: "weekdayShortTue",
 | 
			
		||||
                    value: 2,
 | 
			
		||||
                },
 | 
			
		||||
                {
 | 
			
		||||
                    id: "weekday3",
 | 
			
		||||
                    langKey: "weekdayShortWed",
 | 
			
		||||
                    value: 3,
 | 
			
		||||
                },
 | 
			
		||||
                {
 | 
			
		||||
                    id: "weekday4",
 | 
			
		||||
                    langKey: "weekdayShortTue",
 | 
			
		||||
                    value: 4,
 | 
			
		||||
                },
 | 
			
		||||
                {
 | 
			
		||||
                    id: "weekday5",
 | 
			
		||||
                    langKey: "weekdayShortFri",
 | 
			
		||||
                    value: 5,
 | 
			
		||||
                },
 | 
			
		||||
                {
 | 
			
		||||
                    id: "weekday6",
 | 
			
		||||
                    langKey: "weekdayShortSat",
 | 
			
		||||
                    value: 6,
 | 
			
		||||
                },
 | 
			
		||||
                {
 | 
			
		||||
                    id: "weekday7",
 | 
			
		||||
                    langKey: "weekdayShortSun",
 | 
			
		||||
                    value: 7,
 | 
			
		||||
                },
 | 
			
		||||
            ],
 | 
			
		||||
        };
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
@@ -169,8 +333,13 @@ export default {
 | 
			
		||||
    watch: {
 | 
			
		||||
        "$route.fullPath"() {
 | 
			
		||||
            this.init();
 | 
			
		||||
        }
 | 
			
		||||
        },
 | 
			
		||||
 | 
			
		||||
        neverEnd(value) {
 | 
			
		||||
            if (value) {
 | 
			
		||||
                this.maintenance.recurringEndDate = "";
 | 
			
		||||
            }
 | 
			
		||||
        },
 | 
			
		||||
    },
 | 
			
		||||
    mounted() {
 | 
			
		||||
        this.init();
 | 
			
		||||
@@ -195,8 +364,21 @@ export default {
 | 
			
		||||
                this.maintenance = {
 | 
			
		||||
                    title: "",
 | 
			
		||||
                    description: "",
 | 
			
		||||
                    start_date: "",
 | 
			
		||||
                    end_date: "",
 | 
			
		||||
                    strategy: "single",
 | 
			
		||||
                    active: 1,
 | 
			
		||||
                    recurringStartDate: this.$root.date(dayjs()),
 | 
			
		||||
                    recurringEndDate: "",
 | 
			
		||||
                    intervalDay: 1,
 | 
			
		||||
                    dateTimeRange: [ this.minDate ],
 | 
			
		||||
                    timeRange: [{
 | 
			
		||||
                        hours: 2,
 | 
			
		||||
                        minutes: 0,
 | 
			
		||||
                    }, {
 | 
			
		||||
                        hours: 3,
 | 
			
		||||
                        minutes: 0,
 | 
			
		||||
                    }],
 | 
			
		||||
                    weekdays: [],
 | 
			
		||||
                    daysOfMonth: [],
 | 
			
		||||
                };
 | 
			
		||||
            } else if (this.isEdit) {
 | 
			
		||||
                this.$root.getSocket().emit("getMaintenance", this.$route.params.id, (res) => {
 | 
			
		||||
@@ -332,4 +514,38 @@ textarea {
 | 
			
		||||
.dark-calendar::-webkit-calendar-picker-indicator {
 | 
			
		||||
    filter: invert(1);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
.weekday-picker {
 | 
			
		||||
    display: flex;
 | 
			
		||||
    gap: 10px;
 | 
			
		||||
 | 
			
		||||
    & > div {
 | 
			
		||||
        display: flex;
 | 
			
		||||
        flex-direction: column;
 | 
			
		||||
        align-items: center;
 | 
			
		||||
        width: 40px;
 | 
			
		||||
 | 
			
		||||
        .form-check-inline {
 | 
			
		||||
            margin-right: 0;
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
.day-picker {
 | 
			
		||||
    display: flex;
 | 
			
		||||
    gap: 10px;
 | 
			
		||||
    flex-wrap: wrap;
 | 
			
		||||
 | 
			
		||||
    & > div {
 | 
			
		||||
        display: flex;
 | 
			
		||||
        flex-direction: column;
 | 
			
		||||
        align-items: center;
 | 
			
		||||
        width: 40px;
 | 
			
		||||
 | 
			
		||||
        .form-check-inline {
 | 
			
		||||
            margin-right: 0;
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
</style>
 | 
			
		||||
 
 | 
			
		||||
@@ -44,6 +44,10 @@
 | 
			
		||||
                </div>
 | 
			
		||||
            </div>
 | 
			
		||||
 | 
			
		||||
            <div class="text-center mt-3" style="font-size: 13px;">
 | 
			
		||||
                <a href="https://github.com/louislam/uptime-kuma/wiki/Maintenance" target="_blank">Learn More</a>
 | 
			
		||||
            </div>
 | 
			
		||||
 | 
			
		||||
            <Confirm ref="confirmDelete" btn-style="btn-danger" :yes-text="$t('Yes')" :no-text="$t('No')" @yes="deleteMaintenance">
 | 
			
		||||
                {{ $t("deleteMaintenanceMsg") }}
 | 
			
		||||
            </Confirm>
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user