mirror of
https://github.com/louislam/uptime-kuma.git
synced 2025-03-04 00:15:57 +00:00
feat:mutiple incident support
This commit is contained in:
parent
cd5644d6d2
commit
0d39d03b04
4 changed files with 167 additions and 105 deletions
1
.gitignore
vendored
1
.gitignore
vendored
|
@ -4,6 +4,7 @@ dist
|
||||||
dist-ssr
|
dist-ssr
|
||||||
*.local
|
*.local
|
||||||
.idea
|
.idea
|
||||||
|
.history/
|
||||||
|
|
||||||
/data
|
/data
|
||||||
!/data/.gitkeep
|
!/data/.gitkeep
|
||||||
|
|
|
@ -106,16 +106,10 @@ class StatusPage extends BeanModel {
|
||||||
static async getStatusPageData(statusPage) {
|
static async getStatusPageData(statusPage) {
|
||||||
const config = await statusPage.toPublicJSON();
|
const config = await statusPage.toPublicJSON();
|
||||||
|
|
||||||
// Incident
|
// Incident List
|
||||||
let incident = await R.findOne("incident", " pin = 1 AND active = 1 AND status_page_id = ? ", [
|
const incidentList = await StatusPage.getIncidentList(statusPage.id);
|
||||||
statusPage.id,
|
|
||||||
]);
|
|
||||||
|
|
||||||
if (incident) {
|
const maintenanceList = await StatusPage.getMaintenanceList(statusPage.id);
|
||||||
incident = incident.toPublicJSON();
|
|
||||||
}
|
|
||||||
|
|
||||||
let maintenanceList = await StatusPage.getMaintenanceList(statusPage.id);
|
|
||||||
|
|
||||||
// Public Group List
|
// Public Group List
|
||||||
const publicGroupList = [];
|
const publicGroupList = [];
|
||||||
|
@ -133,7 +127,7 @@ class StatusPage extends BeanModel {
|
||||||
// Response
|
// Response
|
||||||
return {
|
return {
|
||||||
config,
|
config,
|
||||||
incident,
|
incidentList,
|
||||||
publicGroupList,
|
publicGroupList,
|
||||||
maintenanceList,
|
maintenanceList,
|
||||||
};
|
};
|
||||||
|
@ -329,6 +323,29 @@ class StatusPage extends BeanModel {
|
||||||
return [];
|
return [];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get list of incidents
|
||||||
|
* @param {number} statusPageId ID of status page to get incidents for
|
||||||
|
* @returns {object} Object representing incidents sanitized for public
|
||||||
|
*/
|
||||||
|
static async getIncidentList(statusPageId) {
|
||||||
|
try {
|
||||||
|
const publicIncidentList = [];
|
||||||
|
let incidentList = await R.find("incident", " pin = 1 AND active = 1 AND status_page_id = ? ", [
|
||||||
|
statusPageId,
|
||||||
|
]);
|
||||||
|
|
||||||
|
for (const incident of incidentList) {
|
||||||
|
publicIncidentList.push(await incident.toPublicJSON());
|
||||||
|
}
|
||||||
|
|
||||||
|
return publicIncidentList;
|
||||||
|
|
||||||
|
} catch (error) {
|
||||||
|
return [];
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
module.exports = StatusPage;
|
module.exports = StatusPage;
|
||||||
|
|
|
@ -26,9 +26,6 @@ module.exports.statusPageSocketHandler = (socket) => {
|
||||||
throw new Error("slug is not found");
|
throw new Error("slug is not found");
|
||||||
}
|
}
|
||||||
|
|
||||||
await R.exec("UPDATE incident SET pin = 0 WHERE status_page_id = ? ", [
|
|
||||||
statusPageID
|
|
||||||
]);
|
|
||||||
|
|
||||||
let incidentBean;
|
let incidentBean;
|
||||||
|
|
||||||
|
@ -69,14 +66,15 @@ module.exports.statusPageSocketHandler = (socket) => {
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
socket.on("unpinIncident", async (slug, callback) => {
|
socket.on("unpinIncident", async (slug, incident, callback) => {
|
||||||
try {
|
try {
|
||||||
checkLogin(socket);
|
checkLogin(socket);
|
||||||
|
|
||||||
let statusPageID = await StatusPage.slugToID(slug);
|
let statusPageID = await StatusPage.slugToID(slug);
|
||||||
|
|
||||||
await R.exec("UPDATE incident SET pin = 0 WHERE pin = 1 AND status_page_id = ? ", [
|
await R.exec("UPDATE incident SET pin = 0 WHERE pin = 1 AND status_page_id = ? AND id = ? ", [
|
||||||
statusPageID
|
statusPageID,
|
||||||
|
incident.id
|
||||||
]);
|
]);
|
||||||
|
|
||||||
callback({
|
callback({
|
||||||
|
|
|
@ -169,7 +169,7 @@
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div v-else>
|
<div v-else>
|
||||||
<button class="btn btn-primary btn-add-group me-2" @click="createIncident">
|
<button class="btn btn-primary btn-add-group me-2" :disabled="enableEditIncidentMode" @click="createIncident">
|
||||||
<font-awesome-icon icon="bullhorn" />
|
<font-awesome-icon icon="bullhorn" />
|
||||||
{{ $t("Create Incident") }}
|
{{ $t("Create Incident") }}
|
||||||
</button>
|
</button>
|
||||||
|
@ -177,62 +177,64 @@
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<!-- Incident -->
|
<!-- Incident -->
|
||||||
<div v-if="incident !== null" class="shadow-box alert mb-4 p-4 incident" role="alert" :class="incidentClass">
|
<template v-for="(incidentItem, index) in incidentList" :key="incidentItem.id">
|
||||||
<strong v-if="editIncidentMode">{{ $t("Title") }}:</strong>
|
<div v-if="incidentItem !== null" :ref="`incident-${index}`" class="shadow-box alert mb-4 p-4 incident incident-hook" role="alert" :class="incidentClass(index)">
|
||||||
<Editable v-model="incident.title" tag="h4" :contenteditable="editIncidentMode" :noNL="true" class="alert-heading" />
|
<strong v-if="editIncidentMode(index)">{{ $t("Title") }}:</strong>
|
||||||
|
<Editable v-model="incidentItem.title" tag="h4" :contenteditable="editIncidentMode(index)" :noNL="true" class="alert-heading" />
|
||||||
|
|
||||||
<strong v-if="editIncidentMode">{{ $t("Content") }}:</strong>
|
<strong v-if="editIncidentMode(index)">{{ $t("Content") }}:</strong>
|
||||||
<Editable v-if="editIncidentMode" v-model="incident.content" tag="div" :contenteditable="editIncidentMode" class="content" />
|
<Editable v-if="editIncidentMode(index)" v-model="incidentItem.content" tag="div" :contenteditable="editIncidentMode(index)" class="content" />
|
||||||
<div v-if="editIncidentMode" class="form-text">
|
<div v-if="editIncidentMode(index)" class="form-text">
|
||||||
{{ $t("markdownSupported") }}
|
{{ $t("markdownSupported") }}
|
||||||
</div>
|
</div>
|
||||||
<!-- eslint-disable-next-line vue/no-v-html-->
|
<!-- eslint-disable-next-line vue/no-v-html-->
|
||||||
<div v-if="! editIncidentMode" class="content" v-html="incidentHTML"></div>
|
<div v-if="! editIncidentMode(index)" class="content" v-html="incidentHTML(index)"></div>
|
||||||
|
|
||||||
<!-- Incident Date -->
|
<!-- Incident Date -->
|
||||||
<div class="date mt-3">
|
<div class="date mt-3">
|
||||||
{{ $t("Date Created") }}: {{ $root.datetime(incident.createdDate) }} ({{ dateFromNow(incident.createdDate) }})<br />
|
{{ $t("Date Created") }}: {{ $root.datetime(incidentItem.createdDate) }} ({{ dateFromNow(incidentItem.createdDate) }})<br />
|
||||||
<span v-if="incident.lastUpdatedDate">
|
<span v-if="incidentItem.lastUpdatedDate">
|
||||||
{{ $t("Last Updated") }}: {{ $root.datetime(incident.lastUpdatedDate) }} ({{ dateFromNow(incident.lastUpdatedDate) }})
|
{{ $t("Last Updated") }}: {{ $root.datetime(incidentItem.lastUpdatedDate) }} ({{ dateFromNow(incidentItem.lastUpdatedDate) }})
|
||||||
</span>
|
</span>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div v-if="editMode" class="mt-3">
|
<div v-if="editMode" class="mt-3">
|
||||||
<button v-if="editIncidentMode" class="btn btn-light me-2" @click="postIncident">
|
<button v-if="editIncidentMode(index)" class="btn btn-light me-2" @click="postIncident">
|
||||||
<font-awesome-icon icon="bullhorn" />
|
<font-awesome-icon icon="bullhorn" />
|
||||||
{{ $t("Post") }}
|
{{ $t("Post") }}
|
||||||
</button>
|
</button>
|
||||||
|
|
||||||
<button v-if="!editIncidentMode && incident.id" class="btn btn-light me-2" @click="editIncident">
|
<button v-if="!editIncidentMode(index) && incidentItem.id" class="btn btn-light me-2" :disabled="editIncidentMode(editIncidentIndex)" @click="editIncident(index)">
|
||||||
<font-awesome-icon icon="edit" />
|
<font-awesome-icon icon="edit" />
|
||||||
{{ $t("Edit") }}
|
{{ $t("Edit") }}
|
||||||
</button>
|
</button>
|
||||||
|
|
||||||
<button v-if="editIncidentMode" class="btn btn-light me-2" @click="cancelIncident">
|
<button v-if="editIncidentMode(index)" class="btn btn-light me-2" @click="cancelIncident">
|
||||||
<font-awesome-icon icon="times" />
|
<font-awesome-icon icon="times" />
|
||||||
{{ $t("Cancel") }}
|
{{ $t("Cancel") }}
|
||||||
</button>
|
</button>
|
||||||
|
|
||||||
<div v-if="editIncidentMode" class="dropdown d-inline-block me-2">
|
<div v-if="editIncidentMode(index)" class="dropdown d-inline-block me-2">
|
||||||
<button id="dropdownMenuButton1" class="btn btn-secondary dropdown-toggle" type="button" data-bs-toggle="dropdown" aria-expanded="false">
|
<button id="dropdownMenuButton1" class="btn btn-secondary dropdown-toggle" type="button" data-bs-toggle="dropdown" aria-expanded="false">
|
||||||
{{ $t("Style") }}: {{ $t(incident.style) }}
|
{{ $t("Style") }}: {{ $t(incidentItem.style) }}
|
||||||
</button>
|
</button>
|
||||||
<ul class="dropdown-menu" aria-labelledby="dropdownMenuButton1">
|
<ul class="dropdown-menu" aria-labelledby="dropdownMenuButton1">
|
||||||
<li><a class="dropdown-item" href="#" @click="incident.style = 'info'">{{ $t("info") }}</a></li>
|
<li><a class="dropdown-item" href="#" @click="incidentItem.style = 'info'">{{ $t("info") }}</a></li>
|
||||||
<li><a class="dropdown-item" href="#" @click="incident.style = 'warning'">{{ $t("warning") }}</a></li>
|
<li><a class="dropdown-item" href="#" @click="incidentItem.style = 'warning'">{{ $t("warning") }}</a></li>
|
||||||
<li><a class="dropdown-item" href="#" @click="incident.style = 'danger'">{{ $t("danger") }}</a></li>
|
<li><a class="dropdown-item" href="#" @click="incidentItem.style = 'danger'">{{ $t("danger") }}</a></li>
|
||||||
<li><a class="dropdown-item" href="#" @click="incident.style = 'primary'">{{ $t("primary") }}</a></li>
|
<li><a class="dropdown-item" href="#" @click="incidentItem.style = 'primary'">{{ $t("primary") }}</a></li>
|
||||||
<li><a class="dropdown-item" href="#" @click="incident.style = 'light'">{{ $t("light") }}</a></li>
|
<li><a class="dropdown-item" href="#" @click="incidentItem.style = 'light'">{{ $t("light") }}</a></li>
|
||||||
<li><a class="dropdown-item" href="#" @click="incident.style = 'dark'">{{ $t("dark") }}</a></li>
|
<li><a class="dropdown-item" href="#" @click="incidentItem.style = 'dark'">{{ $t("dark") }}</a></li>
|
||||||
</ul>
|
</ul>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<button v-if="!editIncidentMode && incident.id" class="btn btn-light me-2" @click="unpinIncident">
|
<button v-if="!editIncidentMode(index) && incidentItem.id" class="btn btn-light me-2" @click="unpinIncident(index)">
|
||||||
<font-awesome-icon icon="unlink" />
|
<font-awesome-icon icon="unlink" />
|
||||||
{{ $t("Delete") }}
|
{{ $t("Delete") }}
|
||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
<!-- Overall Status -->
|
<!-- Overall Status -->
|
||||||
<div class="shadow-box list p-4 overall-status mb-4">
|
<div class="shadow-box list p-4 overall-status mb-4">
|
||||||
|
@ -370,18 +372,18 @@ import "prismjs/components/prism-css";
|
||||||
import "prismjs/themes/prism-tomorrow.css"; // import syntax highlighting styles
|
import "prismjs/themes/prism-tomorrow.css"; // import syntax highlighting styles
|
||||||
import ImageCropUpload from "vue-image-crop-upload";
|
import ImageCropUpload from "vue-image-crop-upload";
|
||||||
// import Prism Editor
|
// import Prism Editor
|
||||||
|
import DOMPurify from "dompurify";
|
||||||
|
import { marked } from "marked";
|
||||||
|
import VueMultiselect from "vue-multiselect";
|
||||||
import { PrismEditor } from "vue-prism-editor";
|
import { PrismEditor } from "vue-prism-editor";
|
||||||
import "vue-prism-editor/dist/prismeditor.min.css"; // import the styles somewhere
|
import "vue-prism-editor/dist/prismeditor.min.css"; // import the styles somewhere
|
||||||
import { useToast } from "vue-toastification";
|
import { useToast } from "vue-toastification";
|
||||||
import { marked } from "marked";
|
|
||||||
import DOMPurify from "dompurify";
|
|
||||||
import Confirm from "../components/Confirm.vue";
|
import Confirm from "../components/Confirm.vue";
|
||||||
import PublicGroupList from "../components/PublicGroupList.vue";
|
|
||||||
import MaintenanceTime from "../components/MaintenanceTime.vue";
|
import MaintenanceTime from "../components/MaintenanceTime.vue";
|
||||||
import { getResBaseURL } from "../util-frontend";
|
import PublicGroupList from "../components/PublicGroupList.vue";
|
||||||
import { STATUS_PAGE_ALL_DOWN, STATUS_PAGE_ALL_UP, STATUS_PAGE_MAINTENANCE, STATUS_PAGE_PARTIAL_DOWN, UP, MAINTENANCE } from "../util.ts";
|
|
||||||
import Tag from "../components/Tag.vue";
|
import Tag from "../components/Tag.vue";
|
||||||
import VueMultiselect from "vue-multiselect";
|
import { getResBaseURL } from "../util-frontend";
|
||||||
|
import { MAINTENANCE, STATUS_PAGE_ALL_DOWN, STATUS_PAGE_ALL_UP, STATUS_PAGE_MAINTENANCE, STATUS_PAGE_PARTIAL_DOWN, UP } from "../util.ts";
|
||||||
|
|
||||||
const toast = useToast();
|
const toast = useToast();
|
||||||
dayjs.extend(duration);
|
dayjs.extend(duration);
|
||||||
|
@ -434,10 +436,12 @@ export default {
|
||||||
slug: null,
|
slug: null,
|
||||||
enableEditMode: false,
|
enableEditMode: false,
|
||||||
enableEditIncidentMode: false,
|
enableEditIncidentMode: false,
|
||||||
|
editIncidentIndex: -1,
|
||||||
hasToken: false,
|
hasToken: false,
|
||||||
config: {},
|
config: {},
|
||||||
selectedMonitor: null,
|
selectedMonitor: null,
|
||||||
incident: null,
|
incident: null,
|
||||||
|
incidentList: [],
|
||||||
previousIncident: null,
|
previousIncident: null,
|
||||||
showImageCropUpload: false,
|
showImageCropUpload: false,
|
||||||
imgDataUrl: "/icon.svg",
|
imgDataUrl: "/icon.svg",
|
||||||
|
@ -508,10 +512,6 @@ export default {
|
||||||
return this.enableEditMode && this.$root.socket.connected;
|
return this.enableEditMode && this.$root.socket.connected;
|
||||||
},
|
},
|
||||||
|
|
||||||
editIncidentMode() {
|
|
||||||
return this.enableEditIncidentMode;
|
|
||||||
},
|
|
||||||
|
|
||||||
isPublished() {
|
isPublished() {
|
||||||
return this.config.published;
|
return this.config.published;
|
||||||
},
|
},
|
||||||
|
@ -525,10 +525,6 @@ export default {
|
||||||
return {};
|
return {};
|
||||||
},
|
},
|
||||||
|
|
||||||
incidentClass() {
|
|
||||||
return "bg-" + this.incident.style;
|
|
||||||
},
|
|
||||||
|
|
||||||
maintenanceClass() {
|
maintenanceClass() {
|
||||||
return "bg-maintenance";
|
return "bg-maintenance";
|
||||||
},
|
},
|
||||||
|
@ -577,14 +573,6 @@ export default {
|
||||||
return this.overallStatus === STATUS_PAGE_MAINTENANCE;
|
return this.overallStatus === STATUS_PAGE_MAINTENANCE;
|
||||||
},
|
},
|
||||||
|
|
||||||
incidentHTML() {
|
|
||||||
if (this.incident.content != null) {
|
|
||||||
return DOMPurify.sanitize(marked(this.incident.content));
|
|
||||||
} else {
|
|
||||||
return "";
|
|
||||||
}
|
|
||||||
},
|
|
||||||
|
|
||||||
descriptionHTML() {
|
descriptionHTML() {
|
||||||
if (this.config.description != null) {
|
if (this.config.description != null) {
|
||||||
return DOMPurify.sanitize(marked(this.config.description));
|
return DOMPurify.sanitize(marked(this.config.description));
|
||||||
|
@ -710,7 +698,7 @@ export default {
|
||||||
this.imgDataUrl = this.config.icon;
|
this.imgDataUrl = this.config.icon;
|
||||||
}
|
}
|
||||||
|
|
||||||
this.incident = res.data.incident;
|
this.incidentList = res.data.incidentList;
|
||||||
this.maintenanceList = res.data.maintenanceList;
|
this.maintenanceList = res.data.maintenanceList;
|
||||||
this.$root.publicGroupList = res.data.publicGroupList;
|
this.$root.publicGroupList = res.data.publicGroupList;
|
||||||
|
|
||||||
|
@ -952,17 +940,31 @@ export default {
|
||||||
* @returns {void}
|
* @returns {void}
|
||||||
*/
|
*/
|
||||||
createIncident() {
|
createIncident() {
|
||||||
|
const incidentListLength = this.incidentList.length - 1;
|
||||||
|
// if not contain id we assume it wasn't save and if cancel it's will lost all contents
|
||||||
|
if (this.incidentList.some(item => !item.id)) {
|
||||||
|
this.$root.toastError("Please input title and content");
|
||||||
|
return;
|
||||||
|
} else {
|
||||||
this.enableEditIncidentMode = true;
|
this.enableEditIncidentMode = true;
|
||||||
|
const incident = {
|
||||||
if (this.incident) {
|
|
||||||
this.previousIncident = this.incident;
|
|
||||||
}
|
|
||||||
|
|
||||||
this.incident = {
|
|
||||||
title: "",
|
title: "",
|
||||||
content: "",
|
content: "",
|
||||||
style: "primary",
|
style: "primary",
|
||||||
};
|
};
|
||||||
|
|
||||||
|
this.incidentList.push(incident);
|
||||||
|
this.incident = incident;
|
||||||
|
}
|
||||||
|
|
||||||
|
this.editIncidentIndex = incidentListLength + 1;
|
||||||
|
|
||||||
|
// scroll previous into view,cause new not created
|
||||||
|
const lastIncidentRef = this.$refs?.[`incident-${incidentListLength}`]?.[0];
|
||||||
|
lastIncidentRef && lastIncidentRef.scrollIntoView({
|
||||||
|
behavior: "smooth",
|
||||||
|
block: "start",
|
||||||
|
});
|
||||||
},
|
},
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -979,7 +981,7 @@ export default {
|
||||||
|
|
||||||
if (res.ok) {
|
if (res.ok) {
|
||||||
this.enableEditIncidentMode = false;
|
this.enableEditIncidentMode = false;
|
||||||
this.incident = res.incident;
|
this.incidentList[this.editIncidentIndex] = res.incident;
|
||||||
} else {
|
} else {
|
||||||
this.$root.toastError(res.msg);
|
this.$root.toastError(res.msg);
|
||||||
}
|
}
|
||||||
|
@ -990,10 +992,13 @@ export default {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Click Edit Button
|
* Click Edit Button
|
||||||
|
* @param {number} index index of incedentList
|
||||||
* @returns {void}
|
* @returns {void}
|
||||||
*/
|
*/
|
||||||
editIncident() {
|
editIncident(index) {
|
||||||
this.enableEditIncidentMode = true;
|
this.enableEditIncidentMode = true;
|
||||||
|
this.incident = this.incidentList[index];
|
||||||
|
this.editIncidentIndex = index;
|
||||||
this.previousIncident = Object.assign({}, this.incident);
|
this.previousIncident = Object.assign({}, this.incident);
|
||||||
},
|
},
|
||||||
|
|
||||||
|
@ -1005,18 +1010,28 @@ export default {
|
||||||
this.enableEditIncidentMode = false;
|
this.enableEditIncidentMode = false;
|
||||||
|
|
||||||
if (this.previousIncident) {
|
if (this.previousIncident) {
|
||||||
this.incident = this.previousIncident;
|
this.incidentList[this.editIncidentIndex] = this.previousIncident;
|
||||||
this.previousIncident = null;
|
this.previousIncident = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// a new incident cancel should remove them
|
||||||
|
if (!this.incident?.id) {
|
||||||
|
this.incidentList.splice(this.editIncidentIndex, 1);
|
||||||
|
}
|
||||||
|
this.incident = null;
|
||||||
|
this.editIncidentIndex = -1;
|
||||||
},
|
},
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Unpin the incident
|
* Unpin the incident with id
|
||||||
|
* @param {number} index of incident
|
||||||
* @returns {void}
|
* @returns {void}
|
||||||
*/
|
*/
|
||||||
unpinIncident() {
|
unpinIncident(index) {
|
||||||
this.$root.getSocket().emit("unpinIncident", this.slug, () => {
|
const incident = this.incidentList[index];
|
||||||
|
this.$root.getSocket().emit("unpinIncident", this.slug, incident, () => {
|
||||||
this.incident = null;
|
this.incident = null;
|
||||||
|
this.incidentList.splice(index, 1);
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
|
|
||||||
|
@ -1051,6 +1066,37 @@ export default {
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Generate sanitized HTML from maintenance description
|
||||||
|
* @param {number} index Text to sanitize
|
||||||
|
* @returns {string} Sanitized HTML
|
||||||
|
*/
|
||||||
|
incidentClass(index) {
|
||||||
|
return "bg-" + this.incidentList[index].style;
|
||||||
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Generate sanitized HTML from incident description
|
||||||
|
* @param {number} index Text to sanitize
|
||||||
|
* @returns {string} Sanitized HTML
|
||||||
|
*/
|
||||||
|
incidentHTML(index) {
|
||||||
|
if (this.incidentList[index].content != null) {
|
||||||
|
return DOMPurify.sanitize(marked(this.incidentList[index].content));
|
||||||
|
} else {
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Generate sanitized HTML from incident description
|
||||||
|
* @param {number} index Text to sanitize
|
||||||
|
* @returns {string} Sanitized HTML
|
||||||
|
*/
|
||||||
|
editIncidentMode(index) {
|
||||||
|
return this.enableEditIncidentMode && this.editIncidentIndex === index;
|
||||||
|
},
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
</script>
|
</script>
|
||||||
|
|
Loading…
Add table
Reference in a new issue