mirror of
https://github.com/louislam/uptime-kuma.git
synced 2024-11-13 17:14:21 -08:00
Move maintenance under /maintenance
This commit is contained in:
parent
120e578398
commit
bb883e6fa0
|
@ -1,13 +1,7 @@
|
||||||
<template>
|
<template>
|
||||||
<div class="shadow-box mb-3" :style="boxStyle">
|
<div class="shadow-box mb-3" :style="boxStyle">
|
||||||
<div class="list-header">
|
<div class="list-header">
|
||||||
<div class="search-wrapper float-start" style="margin-left: 5px;">
|
<div class="placeholder"></div>
|
||||||
<font-awesome-icon icon="filter" />
|
|
||||||
<select v-model="selectedList" class="form-control" style="margin-left: 5px;">
|
|
||||||
<option value="monitor" selected>{{ $t('Monitors') }}</option>
|
|
||||||
<option value="maintenance">{{ $t('Maintenance') }}</option>
|
|
||||||
</select>
|
|
||||||
</div>
|
|
||||||
<div class="search-wrapper">
|
<div class="search-wrapper">
|
||||||
<a v-if="searchText == ''" class="search-icon">
|
<a v-if="searchText == ''" class="search-icon">
|
||||||
<font-awesome-icon icon="search" />
|
<font-awesome-icon icon="search" />
|
||||||
|
@ -21,39 +15,13 @@
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="monitor-list" :class="{ scrollbar: scrollbar }">
|
<div class="monitor-list" :class="{ scrollbar: scrollbar }">
|
||||||
<div v-if="Object.keys($root.monitorList).length === 0 && selectedList === 'monitor'" class="text-center mt-3">
|
<div v-if="Object.keys($root.monitorList).length === 0" class="text-center mt-3">
|
||||||
{{ $t("No Monitors, please") }} <router-link to="/add">{{ $t("add one") }}</router-link>
|
{{ $t("No Monitors, please") }} <router-link to="/add">{{ $t("add one") }}</router-link>
|
||||||
</div>
|
</div>
|
||||||
<div v-if="Object.keys($root.maintenanceList).length === 0 && selectedList === 'maintenance'" class="text-center mt-3">
|
|
||||||
{{ $t("No Maintenance, please") }} <router-link to="/addMaintenance">{{ $t("add one") }}</router-link>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<template v-if="selectedList === 'maintenance'">
|
<router-link v-for="(item, index) in sortedMonitorList" :key="index" :to="monitorURL(item.id)" class="item" :class="{ 'disabled': ! item.active }">
|
||||||
<router-link
|
|
||||||
v-for="(item, index) in sortedMaintenanceList" :key="index" :to="maintenanceURL(item.id)"
|
|
||||||
class="item" :class="{ 'disabled': !$root.isActiveMaintenance(item.end_date) }"
|
|
||||||
>
|
|
||||||
<div class="row">
|
<div class="row">
|
||||||
<div class="col-9 col-md-8 small-padding">
|
<div class="col-9 col-md-8 small-padding" :class="{ 'monitor-item': $root.userHeartbeatBar == 'bottom' || $root.userHeartbeatBar == 'none' }">
|
||||||
<div class="info">
|
|
||||||
<Uptime :monitor="null" type="maintenance" :pill="true" />
|
|
||||||
{{ item.title }}
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</router-link>
|
|
||||||
</template>
|
|
||||||
|
|
||||||
<template v-if="selectedList === 'monitor'">
|
|
||||||
<router-link
|
|
||||||
v-for="(item, index) in sortedMonitorList" :key="index" :to="monitorURL(item.id)"
|
|
||||||
class="item" :class="{ 'disabled': ! item.active }"
|
|
||||||
>
|
|
||||||
<div class="row">
|
|
||||||
<div
|
|
||||||
class="col-9 col-md-8 small-padding"
|
|
||||||
:class="{ 'monitor-item': $root.userHeartbeatBar == 'bottom' || $root.userHeartbeatBar == 'none' }"
|
|
||||||
>
|
|
||||||
<div class="info">
|
<div class="info">
|
||||||
<Uptime :monitor="item" type="24" :pill="true" />
|
<Uptime :monitor="item" type="24" :pill="true" />
|
||||||
{{ item.name }}
|
{{ item.name }}
|
||||||
|
@ -62,10 +30,7 @@
|
||||||
<Tag v-for="tag in item.tags" :key="tag" :item="tag" :size="'sm'" />
|
<Tag v-for="tag in item.tags" :key="tag" :item="tag" :size="'sm'" />
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div
|
<div v-show="$root.userHeartbeatBar == 'normal'" :key="$root.userHeartbeatBar" class="col-3 col-md-4">
|
||||||
v-show="$root.userHeartbeatBar == 'normal'" :key="$root.userHeartbeatBar"
|
|
||||||
class="col-3 col-md-4"
|
|
||||||
>
|
|
||||||
<HeartbeatBar size="small" :monitor-id="item.id" />
|
<HeartbeatBar size="small" :monitor-id="item.id" />
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
@ -76,7 +41,6 @@
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</router-link>
|
</router-link>
|
||||||
</template>
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
@ -85,7 +49,7 @@
|
||||||
import HeartbeatBar from "../components/HeartbeatBar.vue";
|
import HeartbeatBar from "../components/HeartbeatBar.vue";
|
||||||
import Tag from "../components/Tag.vue";
|
import Tag from "../components/Tag.vue";
|
||||||
import Uptime from "../components/Uptime.vue";
|
import Uptime from "../components/Uptime.vue";
|
||||||
import { getMaintenanceRelativeURL, getMonitorRelativeURL } from "../util.ts";
|
import { getMonitorRelativeURL } from "../util.ts";
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
components: {
|
components: {
|
||||||
|
@ -102,7 +66,6 @@ export default {
|
||||||
data() {
|
data() {
|
||||||
return {
|
return {
|
||||||
searchText: "",
|
searchText: "",
|
||||||
selectedList: "monitor",
|
|
||||||
windowTop: 0,
|
windowTop: 0,
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
|
@ -125,56 +88,6 @@ export default {
|
||||||
|
|
||||||
},
|
},
|
||||||
|
|
||||||
sortedMaintenanceList() {
|
|
||||||
let result = Object.values(this.$root.maintenanceList);
|
|
||||||
|
|
||||||
result.sort((m1, m2) => {
|
|
||||||
|
|
||||||
if (this.$root.isActiveMaintenance(m1.end_date) !== this.$root.isActiveMaintenance(m2.end_date)) {
|
|
||||||
if (!this.$root.isActiveMaintenance(m2.end_date)) {
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
if (!this.$root.isActiveMaintenance(m1.end_date)) {
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (this.$root.isActiveMaintenance(m1.end_date) && this.$root.isActiveMaintenance(m2.end_date)) {
|
|
||||||
if (Date.parse(m1.end_date) < Date.parse(m2.end_date)) {
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (Date.parse(m2.end_date) < Date.parse(m1.end_date)) {
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!this.$root.isActiveMaintenance(m1.end_date) && !this.$root.isActiveMaintenance(m2.end_date)) {
|
|
||||||
if (Date.parse(m1.end_date) < Date.parse(m2.end_date)) {
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (Date.parse(m2.end_date) < Date.parse(m1.end_date)) {
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return m1.title.localeCompare(m2.title);
|
|
||||||
});
|
|
||||||
|
|
||||||
// Simple filter by search text
|
|
||||||
// finds maintenance name
|
|
||||||
if (this.searchText !== "") {
|
|
||||||
const loweredSearchText = this.searchText.toLowerCase();
|
|
||||||
result = result.filter(maintenance => {
|
|
||||||
return maintenance.title.toLowerCase().includes(loweredSearchText)
|
|
||||||
|| maintenance.description.toLowerCase().includes(loweredSearchText);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
return result;
|
|
||||||
},
|
|
||||||
|
|
||||||
sortedMonitorList() {
|
sortedMonitorList() {
|
||||||
let result = Object.values(this.$root.monitorList);
|
let result = Object.values(this.$root.monitorList);
|
||||||
|
|
||||||
|
@ -240,9 +153,6 @@ export default {
|
||||||
monitorURL(id) {
|
monitorURL(id) {
|
||||||
return getMonitorRelativeURL(id);
|
return getMonitorRelativeURL(id);
|
||||||
},
|
},
|
||||||
maintenanceURL(id) {
|
|
||||||
return getMaintenanceRelativeURL(id);
|
|
||||||
},
|
|
||||||
/** Clear the search bar */
|
/** Clear the search bar */
|
||||||
clearSearchText() {
|
clearSearchText() {
|
||||||
this.searchText = "";
|
this.searchText = "";
|
||||||
|
@ -319,11 +229,4 @@ export default {
|
||||||
margin-top: 5px;
|
margin-top: 5px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.bg-maintenance {
|
|
||||||
background-color: $maintenance;
|
|
||||||
}
|
|
||||||
|
|
||||||
select {
|
|
||||||
text-align: center;
|
|
||||||
}
|
|
||||||
</style>
|
</style>
|
||||||
|
|
|
@ -37,19 +37,32 @@
|
||||||
<div class="profile-pic">{{ $root.usernameFirstChar }}</div>
|
<div class="profile-pic">{{ $root.usernameFirstChar }}</div>
|
||||||
<font-awesome-icon icon="angle-down" />
|
<font-awesome-icon icon="angle-down" />
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
<!-- Header's Dropdown Menu -->
|
||||||
<ul class="dropdown-menu">
|
<ul class="dropdown-menu">
|
||||||
|
<!-- Username -->
|
||||||
<li>
|
<li>
|
||||||
<i18n-t v-if="$root.username != null" tag="span" keypath="signedInDisp" class="dropdown-item-text">
|
<i18n-t v-if="$root.username != null" tag="span" keypath="signedInDisp" class="dropdown-item-text">
|
||||||
<strong>{{ $root.username }}</strong>
|
<strong>{{ $root.username }}</strong>
|
||||||
</i18n-t>
|
</i18n-t>
|
||||||
<span v-if="$root.username == null" class="dropdown-item-text">{{ $t("signedInDispDisabled") }}</span>
|
<span v-if="$root.username == null" class="dropdown-item-text">{{ $t("signedInDispDisabled") }}</span>
|
||||||
</li>
|
</li>
|
||||||
|
|
||||||
<li><hr class="dropdown-divider"></li>
|
<li><hr class="dropdown-divider"></li>
|
||||||
|
|
||||||
|
<!-- Functions -->
|
||||||
|
<li>
|
||||||
|
<router-link to="/maintenance" class="dropdown-item" :class="{ active: $route.path.includes('manage-maintenance') }">
|
||||||
|
<font-awesome-icon icon="wrench" /> {{ $t("Maintenance") }}
|
||||||
|
</router-link>
|
||||||
|
</li>
|
||||||
|
|
||||||
<li>
|
<li>
|
||||||
<router-link to="/settings" class="dropdown-item" :class="{ active: $route.path.includes('settings') }">
|
<router-link to="/settings" class="dropdown-item" :class="{ active: $route.path.includes('settings') }">
|
||||||
<font-awesome-icon icon="cog" /> {{ $t("Settings") }}
|
<font-awesome-icon icon="cog" /> {{ $t("Settings") }}
|
||||||
</router-link>
|
</router-link>
|
||||||
</li>
|
</li>
|
||||||
|
|
||||||
<li v-if="$root.loggedIn && $root.socket.token !== 'autoLogin'">
|
<li v-if="$root.loggedIn && $root.socket.token !== 'autoLogin'">
|
||||||
<button class="dropdown-item" @click="$root.logout">
|
<button class="dropdown-item" @click="$root.logout">
|
||||||
<font-awesome-icon icon="sign-out-alt" />
|
<font-awesome-icon icon="sign-out-alt" />
|
||||||
|
@ -77,7 +90,7 @@
|
||||||
|
|
||||||
<!-- Mobile Only -->
|
<!-- Mobile Only -->
|
||||||
<div v-if="$root.isMobile" style="width: 100%; height: 60px;" />
|
<div v-if="$root.isMobile" style="width: 100%; height: 60px;" />
|
||||||
<nav v-if="$root.isMobile && $root.loggedIn" class="bottom-nav scroll">
|
<nav v-if="$root.isMobile && $root.loggedIn" class="bottom-nav">
|
||||||
<router-link to="/dashboard" class="nav-link">
|
<router-link to="/dashboard" class="nav-link">
|
||||||
<div><font-awesome-icon icon="tachometer-alt" /></div>
|
<div><font-awesome-icon icon="tachometer-alt" /></div>
|
||||||
{{ $t("Dashboard") }}
|
{{ $t("Dashboard") }}
|
||||||
|
@ -93,11 +106,6 @@
|
||||||
{{ $t("Add Monitor") }}
|
{{ $t("Add Monitor") }}
|
||||||
</router-link>
|
</router-link>
|
||||||
|
|
||||||
<router-link to="/addMaintenance" class="nav-link">
|
|
||||||
<div><font-awesome-icon icon="wrench" /></div>
|
|
||||||
{{ $t("Add Maintenance") }}
|
|
||||||
</router-link>
|
|
||||||
|
|
||||||
<router-link to="/settings" class="nav-link">
|
<router-link to="/settings" class="nav-link">
|
||||||
<div><font-awesome-icon icon="cog" /></div>
|
<div><font-awesome-icon icon="cog" /></div>
|
||||||
{{ $t("Settings") }}
|
{{ $t("Settings") }}
|
||||||
|
|
|
@ -2,23 +2,7 @@
|
||||||
<div class="container-fluid">
|
<div class="container-fluid">
|
||||||
<div class="row">
|
<div class="row">
|
||||||
<div v-if="!$root.isMobile" class="col-12 col-md-5 col-xl-4">
|
<div v-if="!$root.isMobile" class="col-12 col-md-5 col-xl-4">
|
||||||
<div class="dropdown dropdown-create">
|
<router-link to="/add" class="btn btn-primary mb-3"><font-awesome-icon icon="plus" /> {{ $t("Add New Monitor") }}</router-link>
|
||||||
<button class="btn btn-primary mb-3 dropdown-toggle" type="button" data-bs-toggle="dropdown">
|
|
||||||
<font-awesome-icon icon="plus" /> {{ $t("Create") }}
|
|
||||||
</button>
|
|
||||||
<ul class="dropdown-menu dropdown-menu-end">
|
|
||||||
<li>
|
|
||||||
<button type="button" class="dropdown-item" @click="$router.push('/add')">
|
|
||||||
<font-awesome-icon icon="heartbeat" /> {{ $t("Monitor") }}
|
|
||||||
</button>
|
|
||||||
</li>
|
|
||||||
<li>
|
|
||||||
<button type="button" class="dropdown-item" @click="$router.push('/addMaintenance')">
|
|
||||||
<font-awesome-icon icon="wrench" /> {{ $t("Maintenance") }}
|
|
||||||
</button>
|
|
||||||
</li>
|
|
||||||
</ul>
|
|
||||||
</div>
|
|
||||||
<MonitorList :scrollbar="true" />
|
<MonitorList :scrollbar="true" />
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
@ -45,8 +29,6 @@ export default {
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style lang="scss" scoped>
|
<style lang="scss" scoped>
|
||||||
@import "../assets/vars.scss";
|
|
||||||
|
|
||||||
.container-fluid {
|
.container-fluid {
|
||||||
width: 98%;
|
width: 98%;
|
||||||
}
|
}
|
||||||
|
@ -55,22 +37,4 @@ export default {
|
||||||
display: flex;
|
display: flex;
|
||||||
justify-content: end;
|
justify-content: end;
|
||||||
}
|
}
|
||||||
|
|
||||||
.dark {
|
|
||||||
.dropdown-create {
|
|
||||||
ul {
|
|
||||||
background-color: $dark-bg;
|
|
||||||
border-color: $dark-bg2;
|
|
||||||
border-width: 2px;
|
|
||||||
|
|
||||||
li button {
|
|
||||||
color: $dark-font-color;
|
|
||||||
}
|
|
||||||
|
|
||||||
li button:hover {
|
|
||||||
background-color: $dark-bg2;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
</style>
|
</style>
|
||||||
|
|
|
@ -6,14 +6,12 @@
|
||||||
<div class="shadow-box">
|
<div class="shadow-box">
|
||||||
<div class="row">
|
<div class="row">
|
||||||
<div class="col-md-6">
|
<div class="col-md-6">
|
||||||
<h2 class="mb-2">{{ $t("General") }}</h2>
|
|
||||||
|
|
||||||
<!-- Title -->
|
<!-- Title -->
|
||||||
<div class="my-3">
|
<div class="my-3">
|
||||||
<label for="name" class="form-label">{{ $t("Title") }}</label>
|
<label for="name" class="form-label">{{ $t("Title") }}</label>
|
||||||
<input
|
<input
|
||||||
id="name" v-model="maintenance.title" type="text" class="form-control"
|
id="name" v-model="maintenance.title" type="text" class="form-control"
|
||||||
:placeholder="titlePlaceholder" required
|
required
|
||||||
>
|
>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
@ -22,7 +20,6 @@
|
||||||
<label for="description" class="form-label">{{ $t("Description") }}</label>
|
<label for="description" class="form-label">{{ $t("Description") }}</label>
|
||||||
<textarea
|
<textarea
|
||||||
id="description" v-model="maintenance.description" class="form-control"
|
id="description" v-model="maintenance.description" class="form-control"
|
||||||
:placeholder="descriptionPlaceholder"
|
|
||||||
></textarea>
|
></textarea>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
@ -54,8 +51,7 @@
|
||||||
|
|
||||||
<!-- Start Date Time -->
|
<!-- Start Date Time -->
|
||||||
<div class="my-3">
|
<div class="my-3">
|
||||||
<label for="start_date" class="form-label">{{ $t("Start of maintenance") }}
|
<label for="start_date" class="form-label">{{ $t("Start Date") }}</label>
|
||||||
({{ $root.timezone }})</label>
|
|
||||||
<input
|
<input
|
||||||
id="start_date" v-model="maintenance.start_date" :type="'datetime-local'"
|
id="start_date" v-model="maintenance.start_date" :type="'datetime-local'"
|
||||||
class="form-control" :class="{'dark-calendar': dark }" required
|
class="form-control" :class="{'dark-calendar': dark }" required
|
||||||
|
@ -64,8 +60,7 @@
|
||||||
|
|
||||||
<!-- End Date Time -->
|
<!-- End Date Time -->
|
||||||
<div class="my-3">
|
<div class="my-3">
|
||||||
<label for="end_date" class="form-label">{{ $t("Expected end of maintenance") }}
|
<label for="end_date" class="form-label">{{ $t("End Date") }}</label>
|
||||||
({{ $root.timezone }})</label>
|
|
||||||
<input
|
<input
|
||||||
id="end_date" v-model="maintenance.end_date" :type="'datetime-local'"
|
id="end_date" v-model="maintenance.end_date" :type="'datetime-local'"
|
||||||
class="form-control" :class="{'dark-calendar': dark }" required
|
class="form-control" :class="{'dark-calendar': dark }" required
|
||||||
|
@ -79,14 +74,14 @@
|
||||||
type="checkbox"
|
type="checkbox"
|
||||||
>
|
>
|
||||||
<label class="form-check-label" for="show-powered-by">{{
|
<label class="form-check-label" for="show-powered-by">{{
|
||||||
$t("Show on all pages")
|
$t("Show this Maintenance Message on ALL Status Pages")
|
||||||
}}</label>
|
}}</label>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<!-- Status pages to display maintenance info on -->
|
<!-- Status pages to display maintenance info on -->
|
||||||
<div v-if="!showOnAllPages" class="my-3">
|
<div v-if="!showOnAllPages" class="my-3">
|
||||||
<label for="selected_status_pages" class="form-label">{{
|
<label for="selected_status_pages" class="form-label">{{
|
||||||
$t("Selected status pages")
|
$t("Show this Maintenance Message on which Status Pages")
|
||||||
}}</label>
|
}}</label>
|
||||||
|
|
||||||
<VueMultiselect
|
<VueMultiselect
|
||||||
|
@ -155,25 +150,17 @@ export default {
|
||||||
computed: {
|
computed: {
|
||||||
|
|
||||||
pageName() {
|
pageName() {
|
||||||
return this.$t((this.isAdd) ? "Schedule maintenance" : "Edit");
|
return this.$t((this.isAdd) ? "Schedule Maintenance" : "Edit Maintenance");
|
||||||
},
|
},
|
||||||
|
|
||||||
isAdd() {
|
isAdd() {
|
||||||
return this.$route.path === "/addMaintenance";
|
return this.$route.path === "/add-maintenance";
|
||||||
},
|
},
|
||||||
|
|
||||||
isEdit() {
|
isEdit() {
|
||||||
return this.$route.path.startsWith("/editMaintenance");
|
return this.$route.path.startsWith("/maintenance/edit");
|
||||||
},
|
},
|
||||||
|
|
||||||
titlePlaceholder() {
|
|
||||||
return this.$t("maintenanceTitleExample");
|
|
||||||
},
|
|
||||||
|
|
||||||
descriptionPlaceholder() {
|
|
||||||
return this.$t("maintenanceDescriptionExample");
|
|
||||||
}
|
|
||||||
|
|
||||||
},
|
},
|
||||||
watch: {
|
watch: {
|
||||||
"$route.fullPath"() {
|
"$route.fullPath"() {
|
||||||
|
@ -281,7 +268,7 @@ export default {
|
||||||
toast.success(res.msg);
|
toast.success(res.msg);
|
||||||
this.processing = false;
|
this.processing = false;
|
||||||
this.$root.getMaintenanceList();
|
this.$root.getMaintenanceList();
|
||||||
this.$router.push("/dashboard/maintenance/" + res.maintenanceID);
|
this.$router.push("/maintenance/" + res.maintenanceID);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
} else {
|
} else {
|
||||||
|
|
|
@ -9,7 +9,7 @@
|
||||||
</p>
|
</p>
|
||||||
|
|
||||||
<div class="functions" style="margin-top: 10px;">
|
<div class="functions" style="margin-top: 10px;">
|
||||||
<router-link :to=" '/editMaintenance/' + maintenance.id " class="btn btn-secondary">
|
<router-link :to=" '/maintenance/edit/' + maintenance.id " class="btn btn-secondary">
|
||||||
<font-awesome-icon icon="edit" /> {{ $t("Edit") }}
|
<font-awesome-icon icon="edit" /> {{ $t("Edit") }}
|
||||||
</router-link>
|
</router-link>
|
||||||
<button class="btn btn-danger" @click="deleteDialog">
|
<button class="btn btn-danger" @click="deleteDialog">
|
||||||
|
@ -27,7 +27,7 @@
|
||||||
</button>
|
</button>
|
||||||
<br />
|
<br />
|
||||||
|
|
||||||
<label for="selected_status_pages" class="form-label" style="margin-top: 20px;">{{ $t("Selected status pages") }}</label>
|
<label for="selected_status_pages" class="form-label" style="margin-top: 20px;">{{ $t("Show this Maintenance Message on which Status Pages") }}</label>
|
||||||
<br>
|
<br>
|
||||||
<button v-for="statusPage in selectedStatusPages" :key="statusPage.id" class="btn btn-monitor" style="margin: 5px; cursor: auto; color: white; font-weight: 500;">
|
<button v-for="statusPage in selectedStatusPages" :key="statusPage.id" class="btn btn-monitor" style="margin: 5px; cursor: auto; color: white; font-weight: 500;">
|
||||||
{{ statusPage }}
|
{{ statusPage }}
|
||||||
|
|
168
src/pages/ManageMaintenance.vue
Normal file
168
src/pages/ManageMaintenance.vue
Normal file
|
@ -0,0 +1,168 @@
|
||||||
|
<template>
|
||||||
|
<transition name="slide-fade" appear>
|
||||||
|
<div>
|
||||||
|
<h1 class="mb-3">
|
||||||
|
{{ $t("Maintenance") }}
|
||||||
|
</h1>
|
||||||
|
|
||||||
|
<div>
|
||||||
|
<router-link to="/add-maintenance" class="btn btn-primary mb-3">
|
||||||
|
<font-awesome-icon icon="plus" /> {{ $t("Schedule Maintenance") }}
|
||||||
|
</router-link>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="shadow-box">
|
||||||
|
<span v-if="Object.keys(sortedMaintenanceList).length === 0" class="d-flex align-items-center justify-content-center my-3">
|
||||||
|
{{ $t("No maintenance") }}
|
||||||
|
</span>
|
||||||
|
|
||||||
|
<router-link
|
||||||
|
v-for="(item, index) in sortedMaintenanceList"
|
||||||
|
:key="index"
|
||||||
|
:to="maintenanceURL(item.id)"
|
||||||
|
class="item"
|
||||||
|
:class="{ 'disabled': !$root.isActiveMaintenance(item.end_date) }"
|
||||||
|
>
|
||||||
|
<div>
|
||||||
|
</div>
|
||||||
|
<div class="info">
|
||||||
|
<div class="title">{{ item.title }}</div>
|
||||||
|
<div>{{ item.description }}</div>
|
||||||
|
</div>
|
||||||
|
</router-link>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</transition>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
import { getResBaseURL } from "../util-frontend";
|
||||||
|
import { getMaintenanceRelativeURL } from "../util.ts";
|
||||||
|
|
||||||
|
export default {
|
||||||
|
components: {
|
||||||
|
},
|
||||||
|
data() {
|
||||||
|
return {
|
||||||
|
};
|
||||||
|
},
|
||||||
|
computed: {
|
||||||
|
sortedMaintenanceList() {
|
||||||
|
let result = Object.values(this.$root.maintenanceList);
|
||||||
|
|
||||||
|
result.sort((m1, m2) => {
|
||||||
|
|
||||||
|
if (this.$root.isActiveMaintenance(m1.end_date) !== this.$root.isActiveMaintenance(m2.end_date)) {
|
||||||
|
if (!this.$root.isActiveMaintenance(m2.end_date)) {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
if (!this.$root.isActiveMaintenance(m1.end_date)) {
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (this.$root.isActiveMaintenance(m1.end_date) && this.$root.isActiveMaintenance(m2.end_date)) {
|
||||||
|
if (Date.parse(m1.end_date) < Date.parse(m2.end_date)) {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (Date.parse(m2.end_date) < Date.parse(m1.end_date)) {
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!this.$root.isActiveMaintenance(m1.end_date) && !this.$root.isActiveMaintenance(m2.end_date)) {
|
||||||
|
if (Date.parse(m1.end_date) < Date.parse(m2.end_date)) {
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (Date.parse(m2.end_date) < Date.parse(m1.end_date)) {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return m1.title.localeCompare(m2.title);
|
||||||
|
});
|
||||||
|
|
||||||
|
return result;
|
||||||
|
},
|
||||||
|
},
|
||||||
|
mounted() {
|
||||||
|
|
||||||
|
},
|
||||||
|
methods: {
|
||||||
|
/**
|
||||||
|
* Get the correct URL for the icon
|
||||||
|
* @param {string} icon Path for icon
|
||||||
|
* @returns {string} Correctly formatted path including port numbers
|
||||||
|
*/
|
||||||
|
icon(icon) {
|
||||||
|
if (icon === "/icon.svg") {
|
||||||
|
return icon;
|
||||||
|
} else {
|
||||||
|
return getResBaseURL() + icon;
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
maintenanceURL(id) {
|
||||||
|
return getMaintenanceRelativeURL(id);
|
||||||
|
},
|
||||||
|
},
|
||||||
|
};
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style lang="scss" scoped>
|
||||||
|
@import "../assets/vars.scss";
|
||||||
|
|
||||||
|
.item {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
gap: 10px;
|
||||||
|
text-decoration: none;
|
||||||
|
border-radius: 10px;
|
||||||
|
transition: all ease-in-out 0.15s;
|
||||||
|
padding: 10px;
|
||||||
|
min-height: 90px;
|
||||||
|
|
||||||
|
&:hover {
|
||||||
|
background-color: $highlight-white;
|
||||||
|
}
|
||||||
|
|
||||||
|
&.active {
|
||||||
|
background-color: #cdf8f4;
|
||||||
|
}
|
||||||
|
|
||||||
|
$logo-width: 70px;
|
||||||
|
|
||||||
|
.logo {
|
||||||
|
width: $logo-width;
|
||||||
|
height: $logo-width;
|
||||||
|
|
||||||
|
// Better when the image is loading
|
||||||
|
min-height: 1px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.info {
|
||||||
|
.title {
|
||||||
|
font-weight: bold;
|
||||||
|
font-size: 20px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.slug {
|
||||||
|
font-size: 14px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.dark {
|
||||||
|
.item {
|
||||||
|
&:hover {
|
||||||
|
background-color: $dark-bg2;
|
||||||
|
}
|
||||||
|
|
||||||
|
&.active {
|
||||||
|
background-color: $dark-bg2;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</style>
|
|
@ -15,6 +15,9 @@ import Entry from "./pages/Entry.vue";
|
||||||
import ManageStatusPage from "./pages/ManageStatusPage.vue";
|
import ManageStatusPage from "./pages/ManageStatusPage.vue";
|
||||||
import AddStatusPage from "./pages/AddStatusPage.vue";
|
import AddStatusPage from "./pages/AddStatusPage.vue";
|
||||||
import NotFound from "./pages/NotFound.vue";
|
import NotFound from "./pages/NotFound.vue";
|
||||||
|
import DockerHosts from "./components/settings/Docker.vue";
|
||||||
|
import MaintenanceDetails from "./pages/MaintenanceDetails.vue";
|
||||||
|
import ManageMaintenance from "./pages/ManageMaintenance.vue";
|
||||||
|
|
||||||
// Settings - Sub Pages
|
// Settings - Sub Pages
|
||||||
import Appearance from "./components/settings/Appearance.vue";
|
import Appearance from "./components/settings/Appearance.vue";
|
||||||
|
@ -26,8 +29,6 @@ const Security = () => import("./components/settings/Security.vue");
|
||||||
import Proxies from "./components/settings/Proxies.vue";
|
import Proxies from "./components/settings/Proxies.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 DockerHosts from "./components/settings/Docker.vue";
|
|
||||||
import MaintenanceDetails from "./pages/MaintenanceDetails.vue";
|
|
||||||
|
|
||||||
const routes = [
|
const routes = [
|
||||||
{
|
{
|
||||||
|
@ -64,28 +65,12 @@ const routes = [
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
{
|
|
||||||
path: "/dashboard/maintenance/:id",
|
|
||||||
component: EmptyLayout,
|
|
||||||
children: [
|
|
||||||
{
|
|
||||||
path: "",
|
|
||||||
component: MaintenanceDetails,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
path: "/editMaintenance/:id",
|
|
||||||
component: EditMaintenance,
|
|
||||||
},
|
|
||||||
],
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
path: "/add",
|
path: "/add",
|
||||||
component: EditMonitor,
|
component: EditMonitor,
|
||||||
},
|
},
|
||||||
{
|
|
||||||
path: "/addMaintenance",
|
|
||||||
component: EditMaintenance,
|
|
||||||
},
|
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
@ -146,6 +131,22 @@ const routes = [
|
||||||
path: "/add-status-page",
|
path: "/add-status-page",
|
||||||
component: AddStatusPage,
|
component: AddStatusPage,
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
path: "/maintenance",
|
||||||
|
component: ManageMaintenance,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
path: "/maintenance/:id",
|
||||||
|
component: MaintenanceDetails,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
path: "/add-maintenance",
|
||||||
|
component: EditMaintenance,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
path: "/maintenance/edit/:id",
|
||||||
|
component: EditMaintenance,
|
||||||
|
},
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
|
|
|
@ -282,9 +282,9 @@ function getCryptoRandomInt(min, max) {
|
||||||
}
|
}
|
||||||
exports.getCryptoRandomInt = getCryptoRandomInt;
|
exports.getCryptoRandomInt = getCryptoRandomInt;
|
||||||
/**
|
/**
|
||||||
* Generate a secret
|
* Generate a random alphanumeric string of fixed length
|
||||||
* @param length Lenght of secret to generate
|
* @param length Length of string to generate
|
||||||
* @returns
|
* @returns string
|
||||||
*/
|
*/
|
||||||
function genSecret(length = 64) {
|
function genSecret(length = 64) {
|
||||||
let secret = "";
|
let secret = "";
|
||||||
|
@ -306,6 +306,6 @@ function getMonitorRelativeURL(id) {
|
||||||
}
|
}
|
||||||
exports.getMonitorRelativeURL = getMonitorRelativeURL;
|
exports.getMonitorRelativeURL = getMonitorRelativeURL;
|
||||||
function getMaintenanceRelativeURL(id) {
|
function getMaintenanceRelativeURL(id) {
|
||||||
return "/dashboard/maintenance/" + id;
|
return "/maintenance/" + id;
|
||||||
}
|
}
|
||||||
exports.getMaintenanceRelativeURL = getMaintenanceRelativeURL;
|
exports.getMaintenanceRelativeURL = getMaintenanceRelativeURL;
|
||||||
|
|
|
@ -340,5 +340,5 @@ export function getMonitorRelativeURL(id: string) {
|
||||||
}
|
}
|
||||||
|
|
||||||
export function getMaintenanceRelativeURL(id: string) {
|
export function getMaintenanceRelativeURL(id: string) {
|
||||||
return "/dashboard/maintenance/" + id;
|
return "/maintenance/" + id;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue