feat: allow reduceing the monitor minimum interval to 1 second after accepting a warning (#1740)

Signed-off-by: Zoe Nickson <mnickson@sidingsmedia.com>
Co-authored-by: Frank Elsinga <frank@elsinga.de>
This commit is contained in:
Zoe Nickson 2025-12-09 22:25:23 +00:00 committed by GitHub
parent fd7435fa51
commit 7a34bb0f58
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
4 changed files with 62 additions and 5 deletions

View File

@ -1231,5 +1231,7 @@
"Allow Notifications": "Allow Notifications", "Allow Notifications": "Allow Notifications",
"Browser not supported": "Browser not supported", "Browser not supported": "Browser not supported",
"Unable to get permission to notify": "Unable to get permission to notify (request either denied or ignored).", "Unable to get permission to notify": "Unable to get permission to notify (request either denied or ignored).",
"Webpush Helptext": "Web push only works with SSL (HTTPS) connections. For iOS devices, webpage must be added to homescreen beforehand." "Webpush Helptext": "Web push only works with SSL (HTTPS) connections. For iOS devices, webpage must be added to homescreen beforehand.",
"minimumIntervalWarning": "Intervals below 20 seconds may result in poor performance.",
"lowIntervalWarning": "Are you sure want to set the interval value below 20 seconds? Performance may be degraded, particularly if there are a large number of monitors."
} }

View File

@ -717,10 +717,26 @@
<!-- Interval --> <!-- Interval -->
<div class="my-3"> <div class="my-3">
<label for="interval" class="form-label">{{ $t("Heartbeat Interval") }} ({{ $t("checkEverySecond", [ monitor.interval ]) }})</label> <label for="interval" class="form-label">{{ $t("Heartbeat Interval") }} ({{ $t("checkEverySecond", [ monitor.interval ]) }})</label>
<input id="interval" v-model="monitor.interval" type="number" class="form-control" required :min="minInterval" step="1" :max="maxInterval" @blur="finishUpdateInterval"> <input
id="interval"
v-model="monitor.interval"
type="number"
class="form-control"
required
:min="minInterval"
:max="maxInterval"
step="1"
@focus="lowIntervalConfirmation.editedValue=true"
@blur="checkIntervalValue"
>
<div class="form-text"> <div class="form-text">
{{ monitor.humanReadableInterval }} {{ monitor.humanReadableInterval }}
</div> </div>
<div v-if="monitor.interval < 20" class="form-text">
{{ $t("minimumIntervalWarning") }}
</div>
</div> </div>
<div class="my-3"> <div class="my-3">
@ -736,7 +752,19 @@
{{ $t("Heartbeat Retry Interval") }} {{ $t("Heartbeat Retry Interval") }}
<span>({{ $t("retryCheckEverySecond", [ monitor.retryInterval ]) }})</span> <span>({{ $t("retryCheckEverySecond", [ monitor.retryInterval ]) }})</span>
</label> </label>
<input id="retry-interval" v-model="monitor.retryInterval" type="number" class="form-control" required :min="minInterval" step="1"> <input
id="retry-interval"
v-model="monitor.retryInterval"
type="number"
class="form-control"
required
:min="minInterval"
step="1"
@focus="lowIntervalConfirmation.editedValue=true"
>
<div v-if="monitor.retryInterval < 20" class="form-text">
{{ $t("minimumIntervalWarning") }}
</div>
</div> </div>
<!-- Timeout: HTTP / JSON query / Keyword / Ping / RabbitMQ / SNMP only --> <!-- Timeout: HTTP / JSON query / Keyword / Ping / RabbitMQ / SNMP only -->
@ -1251,6 +1279,10 @@
<ProxyDialog ref="proxyDialog" @added="addedProxy" /> <ProxyDialog ref="proxyDialog" @added="addedProxy" />
<CreateGroupDialog ref="createGroupDialog" @added="addedDraftGroup" /> <CreateGroupDialog ref="createGroupDialog" @added="addedDraftGroup" />
<RemoteBrowserDialog ref="remoteBrowserDialog" /> <RemoteBrowserDialog ref="remoteBrowserDialog" />
<Confirm ref="confirmLowIntervalValue" btn-style="btn-danger" :yes-text="$t('Confirm')" :no-text="$t('Cancel')" @yes="handleIntervalConfirm">
<p>{{ $t("lowIntervalWarning") }}</p>
<p>{{ $t("Please use this option carefully!") }}</p>
</Confirm>
</div> </div>
</transition> </transition>
</template> </template>
@ -1261,6 +1293,7 @@ import { useToast } from "vue-toastification";
import ActionSelect from "../components/ActionSelect.vue"; import ActionSelect from "../components/ActionSelect.vue";
import CopyableInput from "../components/CopyableInput.vue"; import CopyableInput from "../components/CopyableInput.vue";
import CreateGroupDialog from "../components/CreateGroupDialog.vue"; import CreateGroupDialog from "../components/CreateGroupDialog.vue";
import Confirm from "../components/Confirm.vue";
import NotificationDialog from "../components/NotificationDialog.vue"; import NotificationDialog from "../components/NotificationDialog.vue";
import DockerHostDialog from "../components/DockerHostDialog.vue"; import DockerHostDialog from "../components/DockerHostDialog.vue";
import RemoteBrowserDialog from "../components/RemoteBrowserDialog.vue"; import RemoteBrowserDialog from "../components/RemoteBrowserDialog.vue";
@ -1336,6 +1369,7 @@ export default {
ProxyDialog, ProxyDialog,
CopyableInput, CopyableInput,
CreateGroupDialog, CreateGroupDialog,
Confirm,
NotificationDialog, NotificationDialog,
DockerHostDialog, DockerHostDialog,
RemoteBrowserDialog, RemoteBrowserDialog,
@ -1368,6 +1402,10 @@ export default {
}, },
draftGroupName: null, draftGroupName: null,
remoteBrowsersEnabled: false, remoteBrowsersEnabled: false,
lowIntervalConfirmation: {
confirmed: false,
editedValue: false,
},
}; };
}, },
@ -1995,6 +2033,11 @@ message HealthCheckResponse {
this.monitor.pushToken = genSecret(pushTokenLength); this.monitor.pushToken = genSecret(pushTokenLength);
}, },
handleIntervalConfirm() {
this.lowIntervalConfirmation.confirmed = true;
this.submit();
},
/** /**
* Submit the form data for processing * Submit the form data for processing
* @returns {Promise<void>} * @returns {Promise<void>}
@ -2003,6 +2046,15 @@ message HealthCheckResponse {
this.processing = true; this.processing = true;
// Check user has confirmed use of low interval value. Only
// do this if the interval value has changed since last save.
if (this.lowIntervalConfirmation.editedValue && (this.monitor.interval < 20 || this.monitor.retryInterval < 20) && !this.lowIntervalConfirmation.confirmed) {
// The dialog will then re-call submit
this.$refs.confirmLowIntervalValue.show();
this.processing = false;
return;
}
if (!this.monitor.name) { if (!this.monitor.name) {
this.monitor.name = this.defaultFriendlyName; this.monitor.name = this.defaultFriendlyName;
} }
@ -2012,6 +2064,9 @@ message HealthCheckResponse {
return; return;
} }
this.lowIntervalConfirmation.confirmed = false;
this.lowIntervalConfirmation.editedValue = false;
// Beautify the JSON format (only if httpBodyEncoding is not set or === json) // Beautify the JSON format (only if httpBodyEncoding is not set or === json)
if (this.monitor.body && (!this.monitor.httpBodyEncoding || this.monitor.httpBodyEncoding === "json")) { if (this.monitor.body && (!this.monitor.httpBodyEncoding || this.monitor.httpBodyEncoding === "json")) {
this.monitor.body = JSON.stringify(JSON.parse(this.monitor.body), null, 4); this.monitor.body = JSON.stringify(JSON.parse(this.monitor.body), null, 4);

View File

@ -30,7 +30,7 @@ exports.SQL_DATE_FORMAT = "YYYY-MM-DD";
exports.SQL_DATETIME_FORMAT = "YYYY-MM-DD HH:mm:ss"; exports.SQL_DATETIME_FORMAT = "YYYY-MM-DD HH:mm:ss";
exports.SQL_DATETIME_FORMAT_WITHOUT_SECOND = "YYYY-MM-DD HH:mm"; exports.SQL_DATETIME_FORMAT_WITHOUT_SECOND = "YYYY-MM-DD HH:mm";
exports.MAX_INTERVAL_SECOND = 2073600; exports.MAX_INTERVAL_SECOND = 2073600;
exports.MIN_INTERVAL_SECOND = 20; exports.MIN_INTERVAL_SECOND = 1;
exports.PING_PACKET_SIZE_MIN = 1; exports.PING_PACKET_SIZE_MIN = 1;
exports.PING_PACKET_SIZE_MAX = 65500; exports.PING_PACKET_SIZE_MAX = 65500;
exports.PING_PACKET_SIZE_DEFAULT = 56; exports.PING_PACKET_SIZE_DEFAULT = 56;

View File

@ -44,7 +44,7 @@ export const SQL_DATETIME_FORMAT = "YYYY-MM-DD HH:mm:ss";
export const SQL_DATETIME_FORMAT_WITHOUT_SECOND = "YYYY-MM-DD HH:mm"; export const SQL_DATETIME_FORMAT_WITHOUT_SECOND = "YYYY-MM-DD HH:mm";
export const MAX_INTERVAL_SECOND = 2073600; // 24 days export const MAX_INTERVAL_SECOND = 2073600; // 24 days
export const MIN_INTERVAL_SECOND = 20; // 20 seconds export const MIN_INTERVAL_SECOND = 1; // 1 second
// Packet Size limits // Packet Size limits
export const PING_PACKET_SIZE_MIN = 1; export const PING_PACKET_SIZE_MIN = 1;