diff --git a/db/patch9.sql b/db/patch9.sql
new file mode 100644
index 0000000..b4d3991
--- /dev/null
+++ b/db/patch9.sql
@@ -0,0 +1,18 @@
+-- You should not modify if this have pushed to Github, unless it does serious wrong with the db.
+CREATE TABLE tag (
+ id INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT,
+ name VARCHAR(255) NOT NULL,
+ created_date DATETIME DEFAULT (DATETIME('now')) NOT NULL
+);
+
+CREATE TABLE monitor_tag (
+ id INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT,
+ monitor_id INTEGER NOT NULL,
+ tag_id INTEGER NOT NULL,
+ value TEXT,
+ CONSTRAINT FK_tag FOREIGN KEY (tag_id) REFERENCES tag(id) ON DELETE CASCADE ON UPDATE CASCADE,
+ CONSTRAINT FK_monitor FOREIGN KEY (monitor_id) REFERENCES monitor(id) ON DELETE CASCADE ON UPDATE CASCADE
+);
+
+CREATE INDEX monitor_tag_monitor_id_index ON monitor_tag (monitor_id);
+CREATE INDEX monitor_tag_tag_id_index ON monitor_tag (tag_id);
diff --git a/server/model/monitor.js b/server/model/monitor.js
index 19f21d9..6c19f40 100644
--- a/server/model/monitor.js
+++ b/server/model/monitor.js
@@ -32,6 +32,8 @@ class Monitor extends BeanModel {
notificationIDList[bean.notification_id] = true;
}
+ const tags = await R.getAll("SELECT * FROM monitor_tag mt JOIN tag ON mt.tag_id = tag.id WHERE mt.monitor_id = ?", [this.id]);
+
return {
id: this.id,
name: this.name,
@@ -52,6 +54,7 @@ class Monitor extends BeanModel {
dns_resolve_server: this.dns_resolve_server,
dns_last_result: this.dns_last_result,
notificationIDList,
+ tags: tags,
};
}
diff --git a/server/model/tag.js b/server/model/tag.js
new file mode 100644
index 0000000..0c7a58e
--- /dev/null
+++ b/server/model/tag.js
@@ -0,0 +1,12 @@
+const { BeanModel } = require("redbean-node/dist/bean-model");
+
+class Tag extends BeanModel {
+ toJSON() {
+ return {
+ id: this._id,
+ name: this._name,
+ };
+ }
+}
+
+module.exports = Tag;
diff --git a/server/server.js b/server/server.js
index e4cd06e..fc79d7e 100644
--- a/server/server.js
+++ b/server/server.js
@@ -446,6 +446,154 @@ let indexHTML = fs.readFileSync("./dist/index.html").toString();
}
});
+ socket.on("getTags", async (callback) => {
+ try {
+ checkLogin(socket)
+
+ const list = await R.findAll("tag")
+
+ callback({
+ ok: true,
+ tags: list.map(bean => bean.toJSON()),
+ });
+
+ } catch (e) {
+ callback({
+ ok: false,
+ msg: e.message,
+ });
+ }
+ });
+
+ socket.on("addTag", async (tag, callback) => {
+ try {
+ checkLogin(socket)
+
+ let bean = R.dispense("tag")
+ bean.name = tag.name
+ await R.store(bean)
+
+ callback({
+ ok: true,
+ tag: await bean.toJSON(),
+ });
+
+ } catch (e) {
+ callback({
+ ok: false,
+ msg: e.message,
+ });
+ }
+ });
+
+ socket.on("editTag", async (tag, callback) => {
+ try {
+ checkLogin(socket)
+
+ let bean = await R.findOne("monitor", " id = ? ", [ tag.id ])
+ bean.name = tag.name
+ await R.store(bean)
+
+ callback({
+ ok: true,
+ tag: await bean.toJSON(),
+ });
+
+ } catch (e) {
+ callback({
+ ok: false,
+ msg: e.message,
+ });
+ }
+ });
+
+ socket.on("deleteTag", async (tagID, callback) => {
+ try {
+ checkLogin(socket)
+
+ await R.exec("DELETE FROM tag WHERE id = ? ", [ tagID ])
+
+ callback({
+ ok: true,
+ msg: "Deleted Successfully.",
+ });
+
+ } catch (e) {
+ callback({
+ ok: false,
+ msg: e.message,
+ });
+ }
+ });
+
+ socket.on("addMonitorTag", async (tagID, monitorID, value, callback) => {
+ try {
+ checkLogin(socket)
+
+ await R.exec("INSERT INTO monitor_tag (tag_id, monitor_id, value) VALUES (?, ?, ?)", [
+ tagID,
+ monitorID,
+ value,
+ ])
+
+ callback({
+ ok: true,
+ msg: "Added Successfully.",
+ });
+
+ } catch (e) {
+ callback({
+ ok: false,
+ msg: e.message,
+ });
+ }
+ });
+
+ socket.on("editMonitorTag", async (tagID, monitorID, value, callback) => {
+ try {
+ checkLogin(socket)
+
+ await R.exec("UPDATE monitor_tag SET value = ? WHERE tag_id = ? AND monitor_id = ?", [
+ value,
+ tagID,
+ monitorID,
+ ])
+
+ callback({
+ ok: true,
+ msg: "Edited Successfully.",
+ });
+
+ } catch (e) {
+ callback({
+ ok: false,
+ msg: e.message,
+ });
+ }
+ });
+
+ socket.on("deleteMonitorTag", async (tagID, monitorID, callback) => {
+ try {
+ checkLogin(socket)
+
+ await R.exec("DELETE FROM monitor_tag WHERE tag_id = ? AND monitor_id = ?", [
+ tagID,
+ monitorID,
+ ])
+
+ callback({
+ ok: true,
+ msg: "Deleted Successfully.",
+ });
+
+ } catch (e) {
+ callback({
+ ok: false,
+ msg: e.message,
+ });
+ }
+ });
+
socket.on("changePassword", async (password, callback) => {
try {
checkLogin(socket)
diff --git a/src/components/Tag.vue b/src/components/Tag.vue
new file mode 100644
index 0000000..ea31523
--- /dev/null
+++ b/src/components/Tag.vue
@@ -0,0 +1,18 @@
+
+ {{ name }}:{{ value }}
+
+
+
diff --git a/src/components/TagsManager.vue b/src/components/TagsManager.vue
new file mode 100644
index 0000000..be8544e
--- /dev/null
+++ b/src/components/TagsManager.vue
@@ -0,0 +1,42 @@
+
+