Fix: Fix tag removal, reuse and validation

This commit is contained in:
Nelson Chan 2021-09-10 14:22:34 +08:00
parent fcbeed55bf
commit a0e4e96160
2 changed files with 61 additions and 56 deletions

View File

@ -752,13 +752,14 @@ let indexHTML = fs.readFileSync("./dist/index.html").toString();
} }
}); });
socket.on("deleteMonitorTag", async (tagID, monitorID, callback) => { socket.on("deleteMonitorTag", async (tagID, monitorID, value, callback) => {
try { try {
checkLogin(socket) checkLogin(socket)
await R.exec("DELETE FROM monitor_tag WHERE tag_id = ? AND monitor_id = ?", [ await R.exec("DELETE FROM monitor_tag WHERE tag_id = ? AND monitor_id = ? AND value = ?", [
tagID, tagID,
monitorID, monitorID,
value,
]) ])
// Cleanup unused Tags // Cleanup unused Tags

View File

@ -40,7 +40,7 @@
</vue-multiselect> </vue-multiselect>
<div v-if="newDraftTag.select?.id == null" class="d-flex mb-2"> <div v-if="newDraftTag.select?.id == null" class="d-flex mb-2">
<div class="w-50 pe-2"> <div class="w-50 pe-2">
<input v-model="newDraftTag.name" class="form-control" :class="{'is-invalid': newDraftTag.nameInvalid}" placeholder="name" /> <input v-model="newDraftTag.name" class="form-control" :class="{'is-invalid': validateDraftTag.nameInvalid}" placeholder="name" />
<div class="invalid-feedback"> <div class="invalid-feedback">
{{ $t("Tag with this name already exist.") }} {{ $t("Tag with this name already exist.") }}
</div> </div>
@ -77,7 +77,7 @@
</div> </div>
</div> </div>
<div class="mb-2"> <div class="mb-2">
<input v-model="newDraftTag.value" class="form-control" :class="{'is-invalid': newDraftTag.valueInvalid}" :placeholder="$t('value (optional)')" /> <input v-model="newDraftTag.value" class="form-control" :class="{'is-invalid': validateDraftTag.valueInvalid}" :placeholder="$t('value (optional)')" />
<div class="invalid-feedback"> <div class="invalid-feedback">
{{ $t("Tag with this value already exist.") }} {{ $t("Tag with this value already exist.") }}
</div> </div>
@ -86,7 +86,7 @@
<button <button
type="button" type="button"
class="btn btn-secondary float-end" class="btn btn-secondary float-end"
:disabled="processing || newDraftTag.invalid" :disabled="processing || validateDraftTag.invalid"
@click.stop="addDraftTag" @click.stop="addDraftTag"
> >
{{ $t("Add") }} {{ $t("Add") }}
@ -131,7 +131,13 @@ export default {
}, },
computed: { computed: {
tagOptions() { tagOptions() {
return this.existingTags; const tagOptions = this.existingTags;
for (const tag of this.newTags) {
if (!tagOptions.find(t => t.name == tag.name && t.color == tag.color)) {
tagOptions.push(tag);
}
}
return tagOptions;
}, },
selectedTags() { selectedTags() {
return this.preSelectedTags.concat(this.newTags).filter(tag => !this.deleteTags.find(monitorTag => monitorTag.id == tag.id)); return this.preSelectedTags.concat(this.newTags).filter(tag => !this.deleteTags.find(monitorTag => monitorTag.id == tag.id));
@ -155,24 +161,47 @@ export default {
{ name: this.$t("Pink"), { name: this.$t("Pink"),
color: "#DB2777" }, color: "#DB2777" },
] ]
},
validateDraftTag() {
let nameInvalid = false;
let valueInvalid = false;
let invalid = true;
if (this.deleteTags.find(tag => tag.name == this.newDraftTag.select?.name && tag.value == this.newDraftTag.value)) {
// Undo removing a Tag
nameInvalid = false;
valueInvalid = false;
invalid = false;
} else if (this.existingTags.filter(tag => tag.name === this.newDraftTag.name).length > 0) {
// Try to create new tag with existing name
nameInvalid = true;
invalid = true;
} else if (this.newTags.concat(this.preSelectedTags).filter(tag => (
tag.name == this.newDraftTag.select?.name && tag.value == this.newDraftTag.value
) || (
tag.name == this.newDraftTag.name && tag.value == this.newDraftTag.value
)).length > 0) {
// Try to add a tag with existing name and value
valueInvalid = true;
invalid = true;
} else if (this.newDraftTag.select != null) {
// Select an existing tag, no need to validate
invalid = false;
valueInvalid = false;
} else if (this.newDraftTag.color == null || this.newDraftTag.name === "") {
// Missing form inputs
nameInvalid = false;
invalid = true;
} else {
// Looks valid
invalid = false;
nameInvalid = false;
valueInvalid = false;
}
return {
invalid,
nameInvalid,
valueInvalid,
} }
},
watch: {
"newDraftTag.select": function (newSelected) {
this.newDraftTag.select = newSelected;
this.validateDraftTag();
},
"newDraftTag.name": function (newName) {
this.newDraftTag.name = newName;
this.validateDraftTag();
},
"newDraftTag.color": function (newColor) {
this.newDraftTag.color = newColor;
this.validateDraftTag();
},
"newDraftTag.value": function (newValue) {
this.newDraftTag.value = newValue;
this.validateDraftTag();
}, },
}, },
mounted() { mounted() {
@ -197,39 +226,6 @@ export default {
this.deleteTags.push(item); this.deleteTags.push(item);
} }
}, },
validateDraftTag() {
if (this.deleteTags.find(tag => tag.name == this.newDraftTag.select?.name && tag.value == this.newDraftTag.value)) {
// Undo removing a Tag
this.newDraftTag.nameInvalid = false;
this.newDraftTag.valueInvalid = false;
this.newDraftTag.invalid = false;
} else if (this.newTags.concat(this.preSelectedTags).filter(tag => (
tag.name == this.newDraftTag.select?.name && tag.value == this.newDraftTag.value
) || (
tag.name == this.newDraftTag.name && tag.value == this.newDraftTag.value
)).length > 0) {
// Try to add a tag with existing name and value
this.newDraftTag.valueInvalid = true;
this.newDraftTag.invalid = true;
} else if (this.newDraftTag.select != null) {
// Select an existing tag, no need to validate
this.newDraftTag.invalid = false;
this.newDraftTag.valueInvalid = false;
} else if (this.existingTags.filter(tag => tag.name === this.newDraftTag.name).length > 0) {
// Try to create new tag with existing name
this.newDraftTag.nameInvalid = true;
this.newDraftTag.invalid = true;
} else if (this.newDraftTag.color == null || this.newDraftTag.name === "") {
// Missing form inputs
this.newDraftTag.nameInvalid = false;
this.newDraftTag.invalid = true;
} else {
// Looks valid
this.newDraftTag.invalid = false;
this.newDraftTag.nameInvalid = false;
this.newDraftTag.valueInvalid = false;
}
},
textColor(option) { textColor(option) {
if (option.color) { if (option.color) {
return "white"; return "white";
@ -296,6 +292,7 @@ export default {
for (const newTag of this.newTags) { for (const newTag of this.newTags) {
let tagId; let tagId;
if (newTag.id == null) { if (newTag.id == null) {
// Create a New Tag
let newTagResult; let newTagResult;
await this.addTagAsync(newTag).then((res) => { await this.addTagAsync(newTag).then((res) => {
if (!res.ok) { if (!res.ok) {
@ -310,11 +307,18 @@ export default {
return; return;
} }
tagId = newTagResult.id; tagId = newTagResult.id;
// Assign the new ID to the tags of the same name & color
this.newTags.map(tag => {
if (tag.name == newTag.name && tag.color == newTag.color) {
tag.id = newTagResult.id;
}
})
} else { } else {
tagId = newTag.id; tagId = newTag.id;
} }
let newMonitorTagResult; let newMonitorTagResult;
// Assign tag to monitor
await this.addMonitorTagAsync(tagId, monitorId, newTag.value).then((res) => { await this.addMonitorTagAsync(tagId, monitorId, newTag.value).then((res) => {
if (!res.ok) { if (!res.ok) {
toast.error(res.msg); toast.error(res.msg);