diff --git a/src/components/TagEditDialog.vue b/src/components/TagEditDialog.vue
index 80ca32bb9..795589947 100644
--- a/src/components/TagEditDialog.vue
+++ b/src/components/TagEditDialog.vue
@@ -12,7 +12,17 @@
@@ -112,7 +122,11 @@ export default {
updated: {
type: Function,
default: () => {},
- }
+ },
+ existingTags: {
+ type: Array,
+ default: () => [],
+ },
},
data() {
return {
@@ -132,6 +146,7 @@ export default {
removingMonitor: [],
addingMonitor: [],
selectedAddMonitor: null,
+ nameInvalid: false,
};
},
@@ -160,11 +175,16 @@ export default {
watch: {
// Set color option to "Custom" when a unknown color is entered
"tag.color"(to, from) {
- if (colorOptions(this).find(x => x.color === to) == null) {
+ if (to !== "" && colorOptions(this).find(x => x.color === to) == null) {
this.selectedColor.name = this.$t("Custom");
this.selectedColor.color = to;
}
},
+ "tag.name"(to, from) {
+ if (to != null) {
+ this.validate();
+ }
+ },
selectedColor(to, from) {
if (to != null) {
this.tag.color = to.color;
@@ -197,6 +217,35 @@ export default {
this.$refs.confirmDelete.show();
},
+ /**
+ * Reset the editTag form
+ */
+ reset() {
+ this.selectedColor = null;
+ this.tag = {
+ id: null,
+ name: "",
+ color: "",
+ };
+ this.monitors = [];
+ this.removingMonitor = [];
+ this.addingMonitor = [];
+ },
+
+ /**
+ * Check for existing tags of the same name, set invalid input
+ * @returns {boolean} True if editing tag is valid
+ */
+ validate() {
+ this.nameInvalid = false;
+ const sameName = this.existingTags.find((existingTag) => existingTag.name === this.tag.name);
+ if (sameName != null && sameName.id !== this.tag.id) {
+ this.nameInvalid = true;
+ return false;
+ }
+ return true;
+ },
+
/**
* Load tag information for display in the edit dialog
* @param {Object} tag tag object to edit
@@ -228,6 +277,27 @@ export default {
this.processing = true;
let editResult = true;
+ if (!this.validate()) {
+ this.processing = false;
+ return;
+ }
+
+ if (this.tag.id == null) {
+ await this.addTagAsync(this.tag).then((res) => {
+ if (!res.ok) {
+ this.$root.toastRes(res.msg);
+ editResult = false;
+ } else {
+ this.tag.id = res.tag.id;
+ this.updated();
+ }
+ });
+ }
+
+ if (!editResult) {
+ return;
+ }
+
for (let addId of this.addingMonitor) {
await this.addMonitorTagAsync(this.tag.id, addId, "").then((res) => {
if (!res.ok) {
@@ -263,9 +333,9 @@ export default {
* Delete the editing tag from server
* @returns {void}
*/
- deleteTag() {
+ async deleteTag() {
this.processing = true;
- this.$root.getSocket().emit("deleteTag", this.tag.id, (res) => {
+ await this.deleteTagAsync(this.tag.id).then((res) => {
this.$root.toastRes(res);
this.processing = false;
@@ -309,6 +379,28 @@ export default {
return getMonitorRelativeURL(id);
},
+ /**
+ * Add a tag asynchronously
+ * @param {Object} newTag Object representing new tag to add
+ * @returns {Promise
}
+ */
+ addTagAsync(newTag) {
+ return new Promise((resolve) => {
+ this.$root.getSocket().emit("addTag", newTag, resolve);
+ });
+ },
+
+ /**
+ * Delete a tag asynchronously
+ * @param {number} tagId ID of tag to delete
+ * @returns {Promise}
+ */
+ deleteTagAsync(tagId) {
+ return new Promise((resolve) => {
+ this.$root.getSocket().emit("deleteTag", tagId, resolve);
+ });
+ },
+
/**
* Add a tag to a monitor asynchronously
* @param {number} tagId ID of tag to add
diff --git a/src/components/settings/Tags.vue b/src/components/settings/Tags.vue
index 347a6ef29..71ad9b7bd 100644
--- a/src/components/settings/Tags.vue
+++ b/src/components/settings/Tags.vue
@@ -1,5 +1,9 @@
-
+
+
+
+
+