mirror of
https://github.com/louislam/uptime-kuma.git
synced 2024-12-24 14:59:39 -05:00
[status page] many update and save group list
This commit is contained in:
parent
6681f49a58
commit
fd95d41d9f
@ -17,6 +17,7 @@ module.exports = {
|
|||||||
requireConfigFile: false,
|
requireConfigFile: false,
|
||||||
},
|
},
|
||||||
rules: {
|
rules: {
|
||||||
|
"linebreak-style": ["error", "unix"],
|
||||||
"camelcase": ["warn", {
|
"camelcase": ["warn", {
|
||||||
"properties": "never",
|
"properties": "never",
|
||||||
"ignoreImports": true
|
"ignoreImports": true
|
||||||
|
30
db/patch-group-table.sql
Normal file
30
db/patch-group-table.sql
Normal file
@ -0,0 +1,30 @@
|
|||||||
|
-- You should not modify if this have pushed to Github, unless it does serious wrong with the db.
|
||||||
|
BEGIN TRANSACTION;
|
||||||
|
|
||||||
|
create table `group`
|
||||||
|
(
|
||||||
|
id INTEGER not null
|
||||||
|
constraint group_pk
|
||||||
|
primary key autoincrement,
|
||||||
|
name VARCHAR(255) not null,
|
||||||
|
created_date DATETIME default (DATETIME('now')) not null,
|
||||||
|
public BOOLEAN default 0 not null,
|
||||||
|
active BOOLEAN default 1 not null,
|
||||||
|
weight BOOLEAN NOT NULL DEFAULT 1000
|
||||||
|
);
|
||||||
|
|
||||||
|
CREATE TABLE [monitor_group]
|
||||||
|
(
|
||||||
|
[id] INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL,
|
||||||
|
[monitor_id] INTEGER NOT NULL REFERENCES [group] ([id]) ON DELETE CASCADE ON UPDATE CASCADE REFERENCES [monitor] ([id]) ON DELETE CASCADE ON UPDATE CASCADE,
|
||||||
|
[group_id] INTEGER NOT NULL,
|
||||||
|
weight BOOLEAN NOT NULL DEFAULT 1000
|
||||||
|
);
|
||||||
|
|
||||||
|
CREATE INDEX [fk]
|
||||||
|
ON [monitor_group] (
|
||||||
|
[monitor_id],
|
||||||
|
[group_id]);
|
||||||
|
|
||||||
|
|
||||||
|
COMMIT;
|
@ -10,6 +10,7 @@ create table incident
|
|||||||
content TEXT not null,
|
content TEXT not null,
|
||||||
style VARCHAR(30) default 'warning' not null,
|
style VARCHAR(30) default 'warning' not null,
|
||||||
created_date DATETIME default (DATETIME('now')) not null,
|
created_date DATETIME default (DATETIME('now')) not null,
|
||||||
|
last_updated_date DATETIME,
|
||||||
pin BOOLEAN default 1 not null,
|
pin BOOLEAN default 1 not null,
|
||||||
active BOOLEAN default 1 not null
|
active BOOLEAN default 1 not null
|
||||||
);
|
);
|
||||||
|
@ -1,6 +0,0 @@
|
|||||||
BEGIN TRANSACTION;
|
|
||||||
|
|
||||||
alter table monitor
|
|
||||||
add public_weight BOOLEAN default 1000 not null;
|
|
||||||
|
|
||||||
COMMIT;
|
|
@ -1,6 +0,0 @@
|
|||||||
BEGIN TRANSACTION;
|
|
||||||
|
|
||||||
alter table monitor
|
|
||||||
add public BOOLEAN default 0 not null;
|
|
||||||
|
|
||||||
COMMIT;
|
|
@ -18,7 +18,7 @@ exports.startInterval = () => {
|
|||||||
|
|
||||||
// For debug
|
// For debug
|
||||||
if (process.env.TEST_CHECK_VERSION === "1") {
|
if (process.env.TEST_CHECK_VERSION === "1") {
|
||||||
res.data.version = "1000.0.0"
|
res.data.version = "1000.0.0";
|
||||||
}
|
}
|
||||||
|
|
||||||
exports.latestVersion = res.data.version;
|
exports.latestVersion = res.data.version;
|
||||||
|
@ -30,11 +30,10 @@ class Database {
|
|||||||
static patchList = {
|
static patchList = {
|
||||||
"patch-setting-value-type.sql": true,
|
"patch-setting-value-type.sql": true,
|
||||||
"patch-improve-performance.sql": true,
|
"patch-improve-performance.sql": true,
|
||||||
"patch-monitor-public.sql": true,
|
|
||||||
"patch-2fa.sql": true,
|
"patch-2fa.sql": true,
|
||||||
"patch-add-retry-interval-monitor.sql": true,
|
"patch-add-retry-interval-monitor.sql": true,
|
||||||
"patch-monitor-public-weight.sql": true,
|
|
||||||
"patch-incident-table.sql": true,
|
"patch-incident-table.sql": true,
|
||||||
|
"patch-group-table.sql": true,
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -65,7 +64,7 @@ class Database {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Auto map the model to a bean object
|
// Auto map the model to a bean object
|
||||||
R.freeze(true)
|
R.freeze(true);
|
||||||
await R.autoloadModels("./server/model");
|
await R.autoloadModels("./server/model");
|
||||||
|
|
||||||
// Change to WAL
|
// Change to WAL
|
||||||
@ -92,7 +91,7 @@ class Database {
|
|||||||
} else if (version > this.latestVersion) {
|
} else if (version > this.latestVersion) {
|
||||||
console.info("Warning: Database version is newer than expected");
|
console.info("Warning: Database version is newer than expected");
|
||||||
} else {
|
} else {
|
||||||
console.info("Database patch is needed")
|
console.info("Database patch is needed");
|
||||||
|
|
||||||
this.backup(version);
|
this.backup(version);
|
||||||
|
|
||||||
@ -107,11 +106,12 @@ class Database {
|
|||||||
}
|
}
|
||||||
} catch (ex) {
|
} catch (ex) {
|
||||||
await Database.close();
|
await Database.close();
|
||||||
this.restore();
|
|
||||||
|
|
||||||
console.error(ex)
|
console.error(ex);
|
||||||
console.error("Start Uptime-Kuma failed due to patch db failed")
|
console.error("Start Uptime-Kuma failed due to patch db failed");
|
||||||
console.error("Please submit the bug report if you still encounter the problem after restart: https://github.com/louislam/uptime-kuma/issues")
|
console.error("Please submit the bug report if you still encounter the problem after restart: https://github.com/louislam/uptime-kuma/issues");
|
||||||
|
|
||||||
|
this.restore();
|
||||||
process.exit(1);
|
process.exit(1);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -136,7 +136,7 @@ class Database {
|
|||||||
|
|
||||||
try {
|
try {
|
||||||
for (let sqlFilename in this.patchList) {
|
for (let sqlFilename in this.patchList) {
|
||||||
await this.patch2Recursion(sqlFilename, databasePatchedFiles)
|
await this.patch2Recursion(sqlFilename, databasePatchedFiles);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (this.patched) {
|
if (this.patched) {
|
||||||
@ -145,11 +145,13 @@ class Database {
|
|||||||
|
|
||||||
} catch (ex) {
|
} catch (ex) {
|
||||||
await Database.close();
|
await Database.close();
|
||||||
this.restore();
|
|
||||||
|
|
||||||
console.error(ex)
|
console.error(ex);
|
||||||
console.error("Start Uptime-Kuma failed due to patch db failed");
|
console.error("Start Uptime-Kuma failed due to patch db failed");
|
||||||
console.error("Please submit the bug report if you still encounter the problem after restart: https://github.com/louislam/uptime-kuma/issues");
|
console.error("Please submit the bug report if you still encounter the problem after restart: https://github.com/louislam/uptime-kuma/issues");
|
||||||
|
|
||||||
|
this.restore();
|
||||||
|
|
||||||
process.exit(1);
|
process.exit(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -189,7 +191,7 @@ class Database {
|
|||||||
console.log(sqlFilename + " is patched successfully");
|
console.log(sqlFilename + " is patched successfully");
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
console.log(sqlFilename + " is already patched, skip");
|
debug(sqlFilename + " is already patched, skip");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -207,12 +209,12 @@ class Database {
|
|||||||
// Remove all comments (--)
|
// Remove all comments (--)
|
||||||
let lines = text.split("\n");
|
let lines = text.split("\n");
|
||||||
lines = lines.filter((line) => {
|
lines = lines.filter((line) => {
|
||||||
return ! line.startsWith("--")
|
return ! line.startsWith("--");
|
||||||
});
|
});
|
||||||
|
|
||||||
// Split statements by semicolon
|
// Split statements by semicolon
|
||||||
// Filter out empty line
|
// Filter out empty line
|
||||||
text = lines.join("\n")
|
text = lines.join("\n");
|
||||||
|
|
||||||
let statements = text.split(";")
|
let statements = text.split(";")
|
||||||
.map((statement) => {
|
.map((statement) => {
|
||||||
@ -220,7 +222,7 @@ class Database {
|
|||||||
})
|
})
|
||||||
.filter((statement) => {
|
.filter((statement) => {
|
||||||
return statement !== "";
|
return statement !== "";
|
||||||
})
|
});
|
||||||
|
|
||||||
for (let statement of statements) {
|
for (let statement of statements) {
|
||||||
await R.exec(statement);
|
await R.exec(statement);
|
||||||
@ -266,7 +268,7 @@ class Database {
|
|||||||
*/
|
*/
|
||||||
static backup(version) {
|
static backup(version) {
|
||||||
if (! this.backupPath) {
|
if (! this.backupPath) {
|
||||||
console.info("Backup the db")
|
console.info("Backup the db");
|
||||||
this.backupPath = this.dataDir + "kuma.db.bak" + version;
|
this.backupPath = this.dataDir + "kuma.db.bak" + version;
|
||||||
fs.copyFileSync(Database.path, this.backupPath);
|
fs.copyFileSync(Database.path, this.backupPath);
|
||||||
|
|
||||||
|
33
server/model/group.js
Normal file
33
server/model/group.js
Normal file
@ -0,0 +1,33 @@
|
|||||||
|
const { BeanModel } = require("redbean-node/dist/bean-model");
|
||||||
|
const { R } = require("redbean-node");
|
||||||
|
|
||||||
|
class Group extends BeanModel {
|
||||||
|
|
||||||
|
async toPublicJSON() {
|
||||||
|
|
||||||
|
let monitorBeanList = R.convertToBeans("monitor", await R.getAll(`
|
||||||
|
SELECT * FROM monitor, monitor_group
|
||||||
|
WHERE monitor.id = monitor_group.monitor_id
|
||||||
|
AND group_id = ?
|
||||||
|
`, [
|
||||||
|
this.id,
|
||||||
|
]));
|
||||||
|
|
||||||
|
console.log(monitorBeanList);
|
||||||
|
|
||||||
|
let monitorList = [];
|
||||||
|
|
||||||
|
for (let bean of monitorBeanList) {
|
||||||
|
monitorList.push(await bean.toPublicJSON());
|
||||||
|
}
|
||||||
|
|
||||||
|
return {
|
||||||
|
id: this.id,
|
||||||
|
name: this.name,
|
||||||
|
weight: this.weight,
|
||||||
|
monitorList,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
module.exports = Group;
|
@ -10,6 +10,7 @@ class Incident extends BeanModel {
|
|||||||
content: this.content,
|
content: this.content,
|
||||||
pin: this.pin,
|
pin: this.pin,
|
||||||
createdDate: this.createdDate,
|
createdDate: this.createdDate,
|
||||||
|
lastUpdatedDate: this.lastUpdatedDate,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -26,8 +26,10 @@ class Monitor extends BeanModel {
|
|||||||
* Only show necessary data to public
|
* Only show necessary data to public
|
||||||
*/
|
*/
|
||||||
async toPublicJSON() {
|
async toPublicJSON() {
|
||||||
// TODO Only show necessary
|
return {
|
||||||
return this.toJSON();
|
id: this.id,
|
||||||
|
name: this.name,
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -41,7 +41,7 @@ router.get("/api/status-page/incident", async (_, response) => {
|
|||||||
response.json({
|
response.json({
|
||||||
ok: true,
|
ok: true,
|
||||||
incident: (await R.findOne("incident", " pin = 1 AND active = 1")).toPublicJSON(),
|
incident: (await R.findOne("incident", " pin = 1 AND active = 1")).toPublicJSON(),
|
||||||
})
|
});
|
||||||
|
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
send403(response, error.message);
|
send403(response, error.message);
|
||||||
@ -55,15 +55,14 @@ router.get("/api/status-page/monitor-list", async (_request, response) => {
|
|||||||
|
|
||||||
try {
|
try {
|
||||||
await checkPublished();
|
await checkPublished();
|
||||||
const monitorList = {};
|
const publicGroupList = [];
|
||||||
let list = await R.find("monitor", " public = 1 ORDER BY weight DESC, name ", [
|
let list = await R.find("group", " public = 1 ORDER BY weight, name ");
|
||||||
]);
|
|
||||||
|
|
||||||
for (let monitor of list) {
|
for (let groupBean of list) {
|
||||||
monitorList[monitor.id] = await monitor.toJSON();
|
publicGroupList.push(await groupBean.toPublicJSON());
|
||||||
}
|
}
|
||||||
|
|
||||||
response.json(monitorList);
|
response.json(publicGroupList);
|
||||||
|
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
send403(response, error.message);
|
send403(response, error.message);
|
||||||
@ -79,7 +78,7 @@ router.get("/api/status-page/heartbeat", async (_request, response) => {
|
|||||||
|
|
||||||
const monitorList = {};
|
const monitorList = {};
|
||||||
let list = await R.find("", " ", [
|
let list = await R.find("", " ", [
|
||||||
])
|
]);
|
||||||
|
|
||||||
for (let monitor of list) {
|
for (let monitor of list) {
|
||||||
monitorList[monitor.id] = await monitor.toJSON();
|
monitorList[monitor.id] = await monitor.toJSON();
|
||||||
@ -126,7 +125,7 @@ function send403(res, msg = "") {
|
|||||||
res.status(403).json({
|
res.status(403).json({
|
||||||
"status": "fail",
|
"status": "fail",
|
||||||
"msg": msg,
|
"msg": msg,
|
||||||
})
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
module.exports = router;
|
module.exports = router;
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
const { R } = require("redbean-node");
|
const { R } = require("redbean-node");
|
||||||
const { checkLogin } = require("../util-server");
|
const { checkLogin } = require("../util-server");
|
||||||
const dayjs = require("dayjs");
|
const dayjs = require("dayjs");
|
||||||
|
const { debug } = require("../../src/util");
|
||||||
|
|
||||||
module.exports.statusPageSocketHandler = (socket) => {
|
module.exports.statusPageSocketHandler = (socket) => {
|
||||||
|
|
||||||
@ -27,7 +28,13 @@ module.exports.statusPageSocketHandler = (socket) => {
|
|||||||
incidentBean.content = incident.content;
|
incidentBean.content = incident.content;
|
||||||
incidentBean.style = incident.style;
|
incidentBean.style = incident.style;
|
||||||
incidentBean.pin = true;
|
incidentBean.pin = true;
|
||||||
incidentBean.createdDate = R.isoDateTime(dayjs.utc());
|
|
||||||
|
if (incident.id) {
|
||||||
|
incidentBean.lastUpdatedDate = R.isoDateTime(dayjs.utc());
|
||||||
|
} else {
|
||||||
|
incidentBean.createdDate = R.isoDateTime(dayjs.utc());
|
||||||
|
}
|
||||||
|
|
||||||
await R.store(incidentBean);
|
await R.store(incidentBean);
|
||||||
|
|
||||||
callback({
|
callback({
|
||||||
@ -58,4 +65,67 @@ module.exports.statusPageSocketHandler = (socket) => {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
// Save Status Page
|
||||||
|
socket.on("saveStatusPage", async (publicGroupList, callback) => {
|
||||||
|
|
||||||
|
try {
|
||||||
|
checkLogin(socket);
|
||||||
|
|
||||||
|
await R.transaction(async (trx) => {
|
||||||
|
const groupIDList = [];
|
||||||
|
let groupOrder = 1;
|
||||||
|
|
||||||
|
for (let group of publicGroupList) {
|
||||||
|
let groupBean;
|
||||||
|
if (group.id) {
|
||||||
|
groupBean = await trx.findOne("group", " id = ? AND public = 1 ", [
|
||||||
|
group.id
|
||||||
|
]);
|
||||||
|
} else {
|
||||||
|
groupBean = R.dispense("group");
|
||||||
|
}
|
||||||
|
|
||||||
|
groupBean.name = group.name;
|
||||||
|
groupBean.public = true;
|
||||||
|
groupBean.weight = groupOrder++;
|
||||||
|
|
||||||
|
await trx.store(groupBean);
|
||||||
|
|
||||||
|
await trx.exec("DELETE FROM monitor_group WHERE group_id = ? ", [
|
||||||
|
groupBean.id
|
||||||
|
]);
|
||||||
|
|
||||||
|
let monitorOrder = 1;
|
||||||
|
for (let monitor of group.monitorList) {
|
||||||
|
let relationBean = R.dispense("monitor_group");
|
||||||
|
relationBean.weight = monitorOrder++;
|
||||||
|
relationBean.group_id = groupBean.id;
|
||||||
|
relationBean.monitor_id = monitor.id;
|
||||||
|
await trx.store(relationBean);
|
||||||
|
}
|
||||||
|
|
||||||
|
groupIDList.push(groupBean.id);
|
||||||
|
group.id = groupBean.id;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Delete groups that not in the list
|
||||||
|
debug("Delete groups that not in the list");
|
||||||
|
const slots = groupIDList.map(() => "?").join(",");
|
||||||
|
await trx.exec(`DELETE FROM \`group\` WHERE id NOT IN (${slots})`, groupIDList);
|
||||||
|
|
||||||
|
callback({
|
||||||
|
ok: true,
|
||||||
|
publicGroupList,
|
||||||
|
});
|
||||||
|
});
|
||||||
|
} catch (error) {
|
||||||
|
|
||||||
|
callback({
|
||||||
|
ok: false,
|
||||||
|
msg: error.message,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
};
|
};
|
||||||
|
@ -11,12 +11,14 @@ export default {
|
|||||||
data() {
|
data() {
|
||||||
return {
|
return {
|
||||||
publicGroupList: [],
|
publicGroupList: [],
|
||||||
}
|
};
|
||||||
},
|
},
|
||||||
computed: {
|
computed: {
|
||||||
publicMonitorList() {
|
publicMonitorList() {
|
||||||
let result = {};
|
let result = {};
|
||||||
|
|
||||||
|
console.log(this.publicGroupList);
|
||||||
|
|
||||||
for (let group of this.publicGroupList) {
|
for (let group of this.publicGroupList) {
|
||||||
for (let monitor of group.monitorList) {
|
for (let monitor of group.monitorList) {
|
||||||
result[monitor.id] = monitor;
|
result[monitor.id] = monitor;
|
||||||
@ -26,7 +28,7 @@ export default {
|
|||||||
},
|
},
|
||||||
|
|
||||||
publicLastHeartbeatList() {
|
publicLastHeartbeatList() {
|
||||||
let result = {}
|
let result = {};
|
||||||
|
|
||||||
for (let monitorID in this.publicMonitorList) {
|
for (let monitorID in this.publicMonitorList) {
|
||||||
if (this.lastHeartbeatList[monitorID]) {
|
if (this.lastHeartbeatList[monitorID]) {
|
||||||
@ -37,4 +39,4 @@ export default {
|
|||||||
return result;
|
return result;
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
}
|
};
|
||||||
|
@ -37,7 +37,7 @@
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div v-else>
|
<div v-else>
|
||||||
<button class="btn btn-success me-2" @click="leaveEditMode">
|
<button class="btn btn-success me-2" @click="save">
|
||||||
<font-awesome-icon icon="save" />
|
<font-awesome-icon icon="save" />
|
||||||
{{ $t("Save") }}
|
{{ $t("Save") }}
|
||||||
</button>
|
</button>
|
||||||
@ -52,6 +52,7 @@
|
|||||||
{{ $t("Create Incident") }}
|
{{ $t("Create Incident") }}
|
||||||
</button>
|
</button>
|
||||||
|
|
||||||
|
<!--
|
||||||
<button v-if="isPublished" class="btn btn-light me-2" @click="">
|
<button v-if="isPublished" class="btn btn-light me-2" @click="">
|
||||||
<font-awesome-icon icon="save" />
|
<font-awesome-icon icon="save" />
|
||||||
{{ $t("Unpublish") }}
|
{{ $t("Unpublish") }}
|
||||||
@ -60,7 +61,7 @@
|
|||||||
<button v-if="!isPublished" class="btn btn-info me-2" @click="">
|
<button v-if="!isPublished" class="btn btn-info me-2" @click="">
|
||||||
<font-awesome-icon icon="save" />
|
<font-awesome-icon icon="save" />
|
||||||
{{ $t("Publish") }}
|
{{ $t("Publish") }}
|
||||||
</button>
|
</button>-->
|
||||||
|
|
||||||
<!-- Set Default Language -->
|
<!-- Set Default Language -->
|
||||||
<!-- Set theme -->
|
<!-- Set theme -->
|
||||||
@ -84,6 +85,14 @@
|
|||||||
<strong v-if="editIncidentMode">{{ $t("Content") }}:</strong>
|
<strong v-if="editIncidentMode">{{ $t("Content") }}:</strong>
|
||||||
<Editable v-model="incident.content" tag="div" :contenteditable="editIncidentMode" class="content" />
|
<Editable v-model="incident.content" tag="div" :contenteditable="editIncidentMode" class="content" />
|
||||||
|
|
||||||
|
<!-- Incident Date -->
|
||||||
|
<div class="date mt-3">
|
||||||
|
Created: {{ incident.createdDate }} ({{ createdDateFromNow }})<br />
|
||||||
|
<span v-if="incident.lastUpdatedDate">
|
||||||
|
Last Updated: {{ incident.lastUpdatedDate }} ({{ lastUpdatedDateFromNow }})
|
||||||
|
</span>
|
||||||
|
</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" class="btn btn-light me-2" @click="postIncident">
|
||||||
<font-awesome-icon icon="bullhorn" />
|
<font-awesome-icon icon="bullhorn" />
|
||||||
@ -190,6 +199,7 @@ import PublicGroupList from "../components/PublicGroupList.vue";
|
|||||||
import ImageCropUpload from "vue-image-crop-upload";
|
import ImageCropUpload from "vue-image-crop-upload";
|
||||||
import { STATUS_PAGE_ALL_DOWN, STATUS_PAGE_ALL_UP, STATUS_PAGE_PARTIAL_DOWN, UP } from "../util.ts";
|
import { STATUS_PAGE_ALL_DOWN, STATUS_PAGE_ALL_UP, STATUS_PAGE_PARTIAL_DOWN, UP } from "../util.ts";
|
||||||
import { useToast } from "vue-toastification";
|
import { useToast } from "vue-toastification";
|
||||||
|
import dayjs from "dayjs";
|
||||||
const toast = useToast();
|
const toast = useToast();
|
||||||
|
|
||||||
const leavePageMsg = "Do you really want to leave? you have unsaved changes!";
|
const leavePageMsg = "Do you really want to leave? you have unsaved changes!";
|
||||||
@ -309,6 +319,14 @@ export default {
|
|||||||
return this.overallStatus === STATUS_PAGE_ALL_DOWN;
|
return this.overallStatus === STATUS_PAGE_ALL_DOWN;
|
||||||
},
|
},
|
||||||
|
|
||||||
|
createdDateFromNow() {
|
||||||
|
return dayjs.utc(this.incident.createdDate).fromNow();
|
||||||
|
},
|
||||||
|
|
||||||
|
lastUpdatedDateFromNow() {
|
||||||
|
return dayjs.utc(this.incident. lastUpdatedDate).fromNow();
|
||||||
|
}
|
||||||
|
|
||||||
},
|
},
|
||||||
watch: {
|
watch: {
|
||||||
|
|
||||||
@ -360,7 +378,7 @@ export default {
|
|||||||
});
|
});
|
||||||
|
|
||||||
axios.get("/api/status-page/monitor-list").then((res) => {
|
axios.get("/api/status-page/monitor-list").then((res) => {
|
||||||
this.monitorList = res.data;
|
this.$root.publicGroupList = res.data;
|
||||||
});
|
});
|
||||||
|
|
||||||
// 5mins a loop
|
// 5mins a loop
|
||||||
@ -380,8 +398,16 @@ export default {
|
|||||||
this.enableEditMode = true;
|
this.enableEditMode = true;
|
||||||
},
|
},
|
||||||
|
|
||||||
leaveEditMode() {
|
save() {
|
||||||
this.enableEditMode = false;
|
this.$root.getSocket().emit("saveStatusPage", this.$root.publicGroupList, (res) => {
|
||||||
|
if (res.ok) {
|
||||||
|
this.enableEditMode = false;
|
||||||
|
console.log(res);
|
||||||
|
this.$root.publicGroupList = res.publicGroupList;
|
||||||
|
} else {
|
||||||
|
toast.error(res.msg);
|
||||||
|
}
|
||||||
|
});
|
||||||
},
|
},
|
||||||
|
|
||||||
monitorSelectorLabel(monitor) {
|
monitorSelectorLabel(monitor) {
|
||||||
@ -534,7 +560,13 @@ footer {
|
|||||||
|
|
||||||
.incident {
|
.incident {
|
||||||
.content {
|
.content {
|
||||||
min-height: 60px;
|
&[contenteditable=true] {
|
||||||
|
min-height: 60px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.date {
|
||||||
|
font-size: 14px;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -3,8 +3,8 @@ import timezone from "dayjs/plugin/timezone";
|
|||||||
import utc from "dayjs/plugin/utc";
|
import utc from "dayjs/plugin/utc";
|
||||||
import timezones from "timezones-list";
|
import timezones from "timezones-list";
|
||||||
|
|
||||||
dayjs.extend(utc)
|
dayjs.extend(utc);
|
||||||
dayjs.extend(timezone)
|
dayjs.extend(timezone);
|
||||||
|
|
||||||
function getTimezoneOffset(timeZone) {
|
function getTimezoneOffset(timeZone) {
|
||||||
const now = new Date();
|
const now = new Date();
|
||||||
@ -28,7 +28,7 @@ export function timezoneList() {
|
|||||||
name: `(UTC${display}) ${timezone.tzCode}`,
|
name: `(UTC${display}) ${timezone.tzCode}`,
|
||||||
value: timezone.tzCode,
|
value: timezone.tzCode,
|
||||||
time: getTimezoneOffset(timezone.tzCode),
|
time: getTimezoneOffset(timezone.tzCode),
|
||||||
})
|
});
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
console.log("Skip Timezone: " + timezone.tzCode);
|
console.log("Skip Timezone: " + timezone.tzCode);
|
||||||
}
|
}
|
||||||
@ -44,7 +44,7 @@ export function timezoneList() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
})
|
});
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user