[autofix.ci] apply automated fixes

This commit is contained in:
autofix-ci[bot] 2026-01-09 04:18:58 +00:00 committed by GitHub
parent db883c05f2
commit 6fee737028
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
7 changed files with 181 additions and 172 deletions

View File

@ -9,7 +9,16 @@ const { Feed } = require("feed");
const config = require("../config");
const { setting } = require("../util-server");
const { STATUS_PAGE_ALL_DOWN, STATUS_PAGE_ALL_UP, STATUS_PAGE_MAINTENANCE, STATUS_PAGE_PARTIAL_DOWN, UP, MAINTENANCE, DOWN, INCIDENT_PAGE_SIZE } = require("../../src/util");
const {
STATUS_PAGE_ALL_DOWN,
STATUS_PAGE_ALL_UP,
STATUS_PAGE_MAINTENANCE,
STATUS_PAGE_PARTIAL_DOWN,
UP,
MAINTENANCE,
DOWN,
INCIDENT_PAGE_SIZE,
} = require("../../src/util");
class StatusPage extends BeanModel {
/**
@ -300,10 +309,12 @@ class StatusPage extends BeanModel {
const config = await statusPage.toPublicJSON();
// All active incidents
let incidents = await R.find("incident", " pin = 1 AND active = 1 AND status_page_id = ? ORDER BY created_date DESC", [
statusPage.id,
]);
incidents = incidents.map(i => i.toPublicJSON());
let incidents = await R.find(
"incident",
" pin = 1 AND active = 1 AND status_page_id = ? ORDER BY created_date DESC",
[statusPage.id]
);
incidents = incidents.map((i) => i.toPublicJSON());
let maintenanceList = await StatusPage.getMaintenanceList(statusPage.id);
@ -500,18 +511,19 @@ class StatusPage extends BeanModel {
static async getIncidentHistory(statusPageId, page, isPublic = true) {
const offset = (page - 1) * INCIDENT_PAGE_SIZE;
const incidents = await R.find("incident",
" status_page_id = ? ORDER BY created_date DESC LIMIT ? OFFSET ? ",
[ statusPageId, INCIDENT_PAGE_SIZE, offset ]
);
const incidents = await R.find("incident", " status_page_id = ? ORDER BY created_date DESC LIMIT ? OFFSET ? ", [
statusPageId,
INCIDENT_PAGE_SIZE,
offset,
]);
const total = await R.count("incident", " status_page_id = ? ", [ statusPageId ]);
const total = await R.count("incident", " status_page_id = ? ", [statusPageId]);
return {
incidents: incidents.map(i => isPublic ? i.toPublicJSON() : i.toJSON()),
incidents: incidents.map((i) => (isPublic ? i.toPublicJSON() : i.toJSON())),
total,
page,
totalPages: Math.ceil(total / INCIDENT_PAGE_SIZE)
totalPages: Math.ceil(total / INCIDENT_PAGE_SIZE),
};
}

View File

@ -159,7 +159,7 @@ router.get("/api/status-page/:slug/incident-history", cache("5 minutes"), async
const result = await StatusPage.getIncidentHistory(statusPageID, page, true);
response.json({
ok: true,
...result
...result,
});
} catch (error) {
sendHttpError(response, error.message);

View File

@ -111,7 +111,7 @@ module.exports.statusPageSocketHandler = (socket) => {
const result = await StatusPage.getIncidentHistory(statusPageID, page, false);
callback({
ok: true,
...result
...result,
});
} catch (error) {
callback({
@ -131,7 +131,7 @@ module.exports.statusPageSocketHandler = (socket) => {
const result = await StatusPage.getIncidentHistory(statusPageID, page, true);
callback({
ok: true,
...result
...result,
});
} catch (error) {
callback({
@ -150,17 +150,17 @@ module.exports.statusPageSocketHandler = (socket) => {
callback({
ok: false,
msg: "slug is not found",
msgi18n: true
msgi18n: true,
});
return;
}
let bean = await R.findOne("incident", " id = ? AND status_page_id = ? ", [ incidentID, statusPageID ]);
let bean = await R.findOne("incident", " id = ? AND status_page_id = ? ", [incidentID, statusPageID]);
if (!bean) {
callback({
ok: false,
msg: "Incident not found or access denied",
msgi18n: true
msgi18n: true,
});
return;
}
@ -171,12 +171,12 @@ module.exports.statusPageSocketHandler = (socket) => {
callback({
ok: false,
msg: e.message,
msgi18n: true
msgi18n: true,
});
return;
}
const validStyles = [ "info", "warning", "danger", "primary", "light", "dark" ];
const validStyles = ["info", "warning", "danger", "primary", "light", "dark"];
if (!validStyles.includes(incident.style)) {
incident.style = "warning";
}
@ -213,17 +213,17 @@ module.exports.statusPageSocketHandler = (socket) => {
callback({
ok: false,
msg: "slug is not found",
msgi18n: true
msgi18n: true,
});
return;
}
let bean = await R.findOne("incident", " id = ? AND status_page_id = ? ", [ incidentID, statusPageID ]);
let bean = await R.findOne("incident", " id = ? AND status_page_id = ? ", [incidentID, statusPageID]);
if (!bean) {
callback({
ok: false,
msg: "Incident not found or access denied",
msgi18n: true
msgi18n: true,
});
return;
}
@ -253,17 +253,17 @@ module.exports.statusPageSocketHandler = (socket) => {
callback({
ok: false,
msg: "slug is not found",
msgi18n: true
msgi18n: true,
});
return;
}
let bean = await R.findOne("incident", " id = ? AND status_page_id = ? ", [ incidentID, statusPageID ]);
let bean = await R.findOne("incident", " id = ? AND status_page_id = ? ", [incidentID, statusPageID]);
if (!bean) {
callback({
ok: false,
msg: "Incident not found or access denied",
msgi18n: true
msgi18n: true,
});
return;
}

View File

@ -51,12 +51,36 @@
{{ $t("Style") }}: {{ $t(modelValue.style) }}
</button>
<ul class="dropdown-menu" aria-labelledby="dropdownMenuButton1">
<li><a class="dropdown-item" href="#" @click.prevent="updateField('style', 'info')">{{ $t("info") }}</a></li>
<li><a class="dropdown-item" href="#" @click.prevent="updateField('style', 'warning')">{{ $t("warning") }}</a></li>
<li><a class="dropdown-item" href="#" @click.prevent="updateField('style', 'danger')">{{ $t("danger") }}</a></li>
<li><a class="dropdown-item" href="#" @click.prevent="updateField('style', 'primary')">{{ $t("primary") }}</a></li>
<li><a class="dropdown-item" href="#" @click.prevent="updateField('style', 'light')">{{ $t("light") }}</a></li>
<li><a class="dropdown-item" href="#" @click.prevent="updateField('style', 'dark')">{{ $t("dark") }}</a></li>
<li>
<a class="dropdown-item" href="#" @click.prevent="updateField('style', 'info')">
{{ $t("info") }}
</a>
</li>
<li>
<a class="dropdown-item" href="#" @click.prevent="updateField('style', 'warning')">
{{ $t("warning") }}
</a>
</li>
<li>
<a class="dropdown-item" href="#" @click.prevent="updateField('style', 'danger')">
{{ $t("danger") }}
</a>
</li>
<li>
<a class="dropdown-item" href="#" @click.prevent="updateField('style', 'primary')">
{{ $t("primary") }}
</a>
</li>
<li>
<a class="dropdown-item" href="#" @click.prevent="updateField('style', 'light')">
{{ $t("light") }}
</a>
</li>
<li>
<a class="dropdown-item" href="#" @click.prevent="updateField('style', 'dark')">
{{ $t("dark") }}
</a>
</li>
</ul>
</div>
</div>
@ -72,15 +96,15 @@ export default {
required: true,
},
},
emits: [ "update:modelValue", "post", "cancel" ],
emits: ["update:modelValue", "post", "cancel"],
methods: {
updateField(field, value) {
this.$emit("update:modelValue", {
...this.modelValue,
[field]: value
[field]: value,
});
}
}
},
},
};
</script>

View File

@ -15,7 +15,7 @@
v-for="incident in incidents"
:key="incident.id"
class="incident-item"
:class="{ 'resolved': !incident.active }"
:class="{ resolved: !incident.active }"
>
<div class="incident-style-indicator" :class="`bg-${incident.style}`"></div>
<div class="incident-body">
@ -49,9 +49,7 @@
<!-- eslint-disable-next-line vue/no-v-html-->
<div class="incident-content mt-1" v-html="getIncidentHTML(incident.content)"></div>
<div class="incident-meta text-muted small mt-2">
<div>
{{ $t("Created") }}: {{ datetime(incident.createdDate) }}
</div>
<div>{{ $t("Created") }}: {{ datetime(incident.createdDate) }}</div>
<div v-if="incident.lastUpdatedDate">
{{ $t("Last Updated") }}: {{ datetime(incident.lastUpdatedDate) }}
</div>
@ -69,26 +67,22 @@ import datetimeMixin from "../mixins/datetime";
export default {
name: "IncidentHistory",
mixins: [ datetimeMixin ],
mixins: [datetimeMixin],
props: {
incidents: {
type: Array,
default: () => []
default: () => [],
},
editMode: {
type: Boolean,
default: false
default: false,
},
loading: {
type: Boolean,
default: false
}
default: false,
},
},
emits: [
"edit-incident",
"delete-incident",
"resolve-incident"
],
emits: ["edit-incident", "delete-incident", "resolve-incident"],
methods: {
/**
* Get sanitized HTML for incident content
@ -100,8 +94,8 @@ export default {
return DOMPurify.sanitize(marked(content));
}
return "";
}
}
},
},
};
</script>

View File

@ -6,19 +6,12 @@
<h5 class="modal-title">
{{ $t("Edit Incident") }}
</h5>
<button
type="button"
class="btn-close"
data-bs-dismiss="modal"
aria-label="Close"
></button>
<button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close"></button>
</div>
<div class="modal-body">
<form @submit.prevent="submit">
<div class="mb-3">
<label for="incident-title" class="form-label">{{
$t("Title")
}}</label>
<label for="incident-title" class="form-label">{{ $t("Title") }}</label>
<input
id="incident-title"
v-model="form.title"
@ -30,9 +23,7 @@
</div>
<div class="mb-3">
<label for="incident-content" class="form-label">{{
$t("Content")
}}</label>
<label for="incident-content" class="form-label">{{ $t("Content") }}</label>
<textarea
id="incident-content"
v-model="form.content"
@ -44,14 +35,8 @@
</div>
<div class="mb-3">
<label for="incident-style" class="form-label">{{
$t("Style")
}}</label>
<select
id="incident-style"
v-model="form.style"
class="form-select"
>
<label for="incident-style" class="form-label">{{ $t("Style") }}</label>
<select id="incident-style" v-model="form.style" class="form-select">
<option value="info">{{ $t("info") }}</option>
<option value="warning">
{{ $t("warning") }}
@ -68,44 +53,22 @@
</div>
<div class="mb-3 form-check">
<input
id="incident-pin"
v-model="form.pin"
type="checkbox"
class="form-check-input"
/>
<input id="incident-pin" v-model="form.pin" type="checkbox" class="form-check-input" />
<label for="incident-pin" class="form-check-label">
{{ $t("Pin this incident") }}
</label>
<div class="form-text">
{{
$t(
"Pinned incidents are shown prominently on the status page"
)
}}
{{ $t("Pinned incidents are shown prominently on the status page") }}
</div>
</div>
</form>
</div>
<div class="modal-footer">
<button
type="button"
class="btn btn-secondary"
data-bs-dismiss="modal"
>
<button type="button" class="btn btn-secondary" data-bs-dismiss="modal">
{{ $t("Cancel") }}
</button>
<button
type="button"
class="btn btn-primary"
:disabled="processing"
@click="submit"
>
<span
v-if="processing"
class="spinner-border spinner-border-sm me-1"
role="status"
></span>
<button type="button" class="btn btn-primary" :disabled="processing" @click="submit">
<span v-if="processing" class="spinner-border spinner-border-sm me-1" role="status"></span>
{{ $t("Save") }}
</button>
</div>
@ -139,7 +102,7 @@ export default {
required: true,
},
},
emits: [ "incident-updated" ],
emits: ["incident-updated"],
data() {
return {
modal: null,
@ -201,22 +164,14 @@ export default {
this.processing = true;
this.$root
.getSocket()
.emit(
"editIncident",
this.slug,
this.incidentId,
this.form,
(res) => {
this.processing = false;
this.$root.toastRes(res);
if (res.ok) {
this.modal.hide();
this.$emit("incident-updated");
}
}
);
this.$root.getSocket().emit("editIncident", this.slug, this.incidentId, this.form, (res) => {
this.processing = false;
this.$root.toastRes(res);
if (res.ok) {
this.modal.hide();
this.$emit("incident-updated");
}
});
},
/**
@ -228,20 +183,13 @@ export default {
return;
}
this.$root
.getSocket()
.emit(
"deleteIncident",
this.slug,
this.pendingDeleteIncident.id,
(res) => {
this.$root.toastRes(res);
if (res.ok) {
this.$emit("incident-updated");
}
this.pendingDeleteIncident = null;
}
);
this.$root.getSocket().emit("deleteIncident", this.slug, this.pendingDeleteIncident.id, (res) => {
this.$root.toastRes(res);
if (res.ok) {
this.$emit("incident-updated");
}
this.pendingDeleteIncident = null;
});
},
},
};

View File

@ -303,7 +303,11 @@
<!-- Incident Edit Form -->
<IncidentEditForm
v-if="editIncidentMode && incident !== null && (!incident.id || !activeIncidents.some(i => i.id === incident.id))"
v-if="
editIncidentMode &&
incident !== null &&
(!incident.id || !activeIncidents.some((i) => i.id === incident.id))
"
v-model="incident"
@post="postIncident"
@cancel="cancelIncident"
@ -329,13 +333,22 @@
>
<h4 class="alert-heading" data-testid="incident-title">{{ activeIncident.title }}</h4>
<!-- eslint-disable-next-line vue/no-v-html-->
<div class="content" data-testid="incident-content" v-html="getIncidentHTML(activeIncident.content)"></div>
<div
class="content"
data-testid="incident-content"
v-html="getIncidentHTML(activeIncident.content)"
></div>
<!-- Incident Date -->
<div class="date mt-3">
{{ $t("Date Created") }}: {{ $root.datetime(activeIncident.createdDate) }} ({{ dateFromNow(activeIncident.createdDate) }})<br />
{{ $t("Date Created") }}: {{ $root.datetime(activeIncident.createdDate) }} ({{
dateFromNow(activeIncident.createdDate)
}})
<br />
<span v-if="activeIncident.lastUpdatedDate">
{{ $t("Last Updated") }}: {{ $root.datetime(activeIncident.lastUpdatedDate) }} ({{ dateFromNow(activeIncident.lastUpdatedDate) }})
{{ $t("Last Updated") }}: {{ $root.datetime(activeIncident.lastUpdatedDate) }} ({{
dateFromNow(activeIncident.lastUpdatedDate)
}})
</span>
</div>
@ -348,7 +361,10 @@
<font-awesome-icon icon="edit" />
{{ $t("Edit") }}
</button>
<button class="btn btn-light me-2" @click="$refs.incidentManageModal.showDelete(activeIncident)">
<button
class="btn btn-light me-2"
@click="$refs.incidentManageModal.showDelete(activeIncident)"
>
<font-awesome-icon icon="unlink" />
{{ $t("Delete") }}
</button>
@ -492,7 +508,11 @@
</div>
<template v-else>
<div v-for="(dateGroup, dateKey) in groupedIncidentHistory" :key="dateKey" class="incident-date-group mb-4">
<div
v-for="(dateGroup, dateKey) in groupedIncidentHistory"
:key="dateKey"
class="incident-date-group mb-4"
>
<h4 class="incident-date-header">{{ dateKey }}</h4>
<div class="shadow-box incident-list-box">
<IncidentHistory
@ -506,13 +526,20 @@
</div>
</div>
<div v-if="incidentHistoryPage < incidentHistoryTotalPages" class="load-more-controls d-flex justify-content-center mt-3">
<div
v-if="incidentHistoryPage < incidentHistoryTotalPages"
class="load-more-controls d-flex justify-content-center mt-3"
>
<button
class="btn btn-outline-secondary btn-sm"
:disabled="incidentHistoryLoading"
@click="loadMoreIncidentHistory"
>
<span v-if="incidentHistoryLoading" class="spinner-border spinner-border-sm me-1" role="status"></span>
<span
v-if="incidentHistoryLoading"
class="spinner-border spinner-border-sm me-1"
role="status"
></span>
{{ $t("Load More") }}
</button>
</div>
@ -845,7 +872,7 @@ export default {
* @returns {object[]} List of active pinned incidents
*/
activeIncidents() {
return this.incidentHistory.filter(i => i.active && i.pin);
return this.incidentHistory.filter((i) => i.active && i.pin);
},
/**
@ -862,7 +889,7 @@ export default {
groups[dateKey].push(incident);
}
return groups;
}
},
},
watch: {
/**
@ -957,23 +984,26 @@ export default {
.then((res) => {
this.config = res.data.config;
if (!this.config.domainNameList) {
this.config.domainNameList = [];
}
if (!this.config.domainNameList) {
this.config.domainNameList = [];
}
if (this.config.icon) {
this.imgDataUrl = this.config.icon;
}
if (this.config.icon) {
this.imgDataUrl = this.config.icon;
}
this.maintenanceList = res.data.maintenanceList;
this.$root.publicGroupList = res.data.publicGroupList;
this.maintenanceList = res.data.maintenanceList;
this.$root.publicGroupList = res.data.publicGroupList;
this.loading = false;
this.loadIncidentHistory();
this.loading = false;
this.loadIncidentHistory();
feedInterval = setInterval(() => {
this.updateHeartbeatList();
}, Math.max(5, this.config.autoRefreshInterval) * 1000);
feedInterval = setInterval(
() => {
this.updateHeartbeatList();
},
Math.max(5, this.config.autoRefreshInterval) * 1000
);
this.incident = res.data.incident;
this.maintenanceList = res.data.maintenanceList;
@ -1378,7 +1408,7 @@ export default {
this.incidentHistoryLoading = false;
if (res.ok) {
if (append) {
this.incidentHistory = [ ...this.incidentHistory, ...res.incidents ];
this.incidentHistory = [...this.incidentHistory, ...res.incidents];
} else {
this.incidentHistory = res.incidents;
}
@ -1390,21 +1420,24 @@ export default {
}
});
} else {
axios.get(`/api/status-page/${this.slug}/incident-history?page=${page}`).then((res) => {
this.incidentHistoryLoading = false;
if (res.data.ok) {
if (append) {
this.incidentHistory = [ ...this.incidentHistory, ...res.data.incidents ];
} else {
this.incidentHistory = res.data.incidents;
axios
.get(`/api/status-page/${this.slug}/incident-history?page=${page}`)
.then((res) => {
this.incidentHistoryLoading = false;
if (res.data.ok) {
if (append) {
this.incidentHistory = [...this.incidentHistory, ...res.data.incidents];
} else {
this.incidentHistory = res.data.incidents;
}
this.incidentHistoryPage = res.data.page;
this.incidentHistoryTotalPages = res.data.totalPages;
}
this.incidentHistoryPage = res.data.page;
this.incidentHistoryTotalPages = res.data.totalPages;
}
}).catch((error) => {
this.incidentHistoryLoading = false;
console.error("Failed to load incident history:", error);
});
})
.catch((error) => {
this.incidentHistoryLoading = false;
console.error("Failed to load incident history:", error);
});
}
},
@ -1431,7 +1464,7 @@ export default {
return date.toLocaleDateString(undefined, {
year: "numeric",
month: "long",
day: "numeric"
day: "numeric",
});
},
@ -1448,8 +1481,7 @@ export default {
}
});
},
}
},
};
</script>
@ -1740,5 +1772,4 @@ footer {
padding: 0;
}
}
</style>