Skip to content

Commit 11cfe61

Browse files
committed
refactor(ui): refactor Tags stores, typing and components
1 parent c220ac7 commit 11cfe61

22 files changed

Lines changed: 365 additions & 612 deletions

ui/src/components/Tags/TagAutocompleteSelect.vue

Lines changed: 3 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -32,16 +32,15 @@
3232
<script setup lang="ts">
3333
import { ref, computed, onMounted, nextTick, onUnmounted } from "vue";
3434
import { useIntersectionObserver } from "@vueuse/core";
35-
import { ITag } from "@/interfaces/ITags";
3635
import useSnackbar from "@/helpers/snackbar";
3736
import useTagsStore from "@/store/modules/tags";
3837
import handleError from "@/utils/handleError";
3938
4039
const tagsStore = useTagsStore();
4140
const snackbar = useSnackbar();
4241
43-
const tags = ref<ITag[]>([]);
44-
const hasMoreTagsToLoad = computed(() => tagsStore.numberTags > tags.value.length);
42+
const tags = ref(tagsStore.tags);
43+
const hasMoreTagsToLoad = computed(() => tagsStore.tagCount > tags.value.length);
4544
const selectedTags = defineModel<string[]>("selectedTags", { required: true });
4645
const tagSelectorErrorMessage = defineModel<string>("tagSelectorErrorMessage", { required: true });
4746
const isAutocompleteMenuOpen = ref(false);
@@ -76,11 +75,10 @@ const loadTags = async () => {
7675
isLoading.value = true;
7776
7877
try {
79-
await tagsStore.autocomplete({
78+
await tagsStore.fetchTagList({
8079
filter: encodeFilter(filter.value),
8180
perPage: itemsPerPage.value,
8281
});
83-
tags.value = tagsStore.list;
8482
} catch (error) {
8583
snackbar.showError("Failed to load tags.");
8684
handleError(error);

ui/src/components/Tags/TagCreate.vue

Lines changed: 19 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -13,20 +13,22 @@
1313
@cancel="close"
1414
@confirm="create"
1515
>
16-
<div class="px-6 pt-4">
16+
<div class="pa-6">
1717
<v-text-field
18-
v-model="inputTags"
18+
v-model="tagInput"
1919
label="Tag name"
20-
:error-messages="tagsError"
20+
:error-messages="tagError"
2121
required
22+
hide-details="auto"
2223
data-test="tag-field"
24+
@update:model-value="validateTagInput"
2325
/>
2426
</div>
2527
</FormDialog>
2628
</template>
2729

2830
<script setup lang="ts">
29-
import { ref, computed, watch } from "vue";
31+
import { ref, computed } from "vue";
3032
import FormDialog from "@/components/Dialogs/FormDialog.vue";
3133
import handleError from "@/utils/handleError";
3234
import useSnackbar from "@/helpers/snackbar";
@@ -37,25 +39,19 @@ const tagsStore = useTagsStore();
3739
const snackbar = useSnackbar();
3840
const showDialog = defineModel<boolean>({ required: true });
3941
40-
const inputTags = ref<string>("");
41-
const tagsError = ref("");
42-
const tagsHasLessThan3Characters = computed(() => inputTags.value.length < 3);
43-
const tenant = computed(() => localStorage.getItem("tenant"));
42+
const tagInput = ref<string>("");
43+
const tagError = ref("");
44+
const confirmDisabled = computed(() => !tagInput.value || !!tagError.value);
4445
45-
watch(inputTags, () => {
46-
if (inputTags.value.length > 255) {
47-
tagsError.value = "Maximum of 3 tags";
48-
} else if (tagsHasLessThan3Characters.value) {
49-
tagsError.value = "The minimum length is 3 characters";
50-
} else {
51-
tagsError.value = "";
52-
}
53-
});
54-
55-
const confirmDisabled = computed(() => !inputTags.value || !!tagsError.value);
46+
const validateTagInput = () => {
47+
const inputLength = tagInput.value.length;
48+
if (inputLength > 255) tagError.value = "The maximum length is 255 characters";
49+
else if (inputLength < 3) tagError.value = "The minimum length is 3 characters";
50+
else tagError.value = "";
51+
};
5652
5753
const close = () => {
58-
inputTags.value = "";
54+
tagInput.value = "";
5955
showDialog.value = false;
6056
};
6157
@@ -65,13 +61,10 @@ const update = () => {
6561
};
6662
6763
const create = async () => {
68-
if (tagsError.value) return;
64+
if (tagError.value) return;
6965
7066
try {
71-
await tagsStore.createTag({
72-
tenant: tenant.value || "",
73-
name: inputTags.value,
74-
});
67+
await tagsStore.createTag(tagInput.value);
7568
7669
snackbar.showSuccess("Successfully created tag");
7770
update();
@@ -81,5 +74,5 @@ const create = async () => {
8174
}
8275
};
8376
84-
defineExpose({ inputTags, showDialog });
77+
defineExpose({ tagInput, showDialog });
8578
</script>

ui/src/components/Tags/TagEdit.vue

Lines changed: 29 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -5,11 +5,8 @@
55
data-test="open-tag-edit"
66
@click="open"
77
>
8-
<div class="d-flex align-center">
9-
<div class="mr-2">
10-
<v-icon> mdi-pencil </v-icon>
11-
</div>
12-
8+
<div class="d-flex align-center ga-2">
9+
<v-icon icon="mdi-pencil"> mdi-pencil </v-icon>
1310
<v-list-item-title data-test="mdi-information-list-item">
1411
Edit
1512
</v-list-item-title>
@@ -30,62 +27,56 @@
3027
@cancel="close"
3128
@confirm="edit"
3229
>
33-
<div class="px-6 pt-4">
30+
<div class="pa-6">
3431
<v-text-field
35-
v-model="inputTags"
32+
v-model="tagInput"
3633
label="Tag name"
37-
:error-messages="tagsError"
34+
hide-details="auto"
35+
:error-messages="tagError"
3836
required
3937
data-test="tag-field"
38+
@update:model-value="validateTagInput"
4039
/>
4140
</div>
4241
</FormDialog>
4342
</template>
4443

4544
<script setup lang="ts">
46-
import { ref, computed, watch } from "vue";
45+
import { ref, computed } from "vue";
4746
import FormDialog from "@/components/Dialogs/FormDialog.vue";
4847
import handleError from "@/utils/handleError";
4948
import useSnackbar from "@/helpers/snackbar";
5049
import useTagsStore from "@/store/modules/tags";
5150
52-
const props = defineProps({
53-
tagName: { type: String, required: true },
54-
hasAuthorization: { type: Boolean, default: false },
55-
});
51+
const props = defineProps<{
52+
tagName: string;
53+
hasAuthorization?: boolean;
54+
}>();
5655
5756
const emit = defineEmits(["update"]);
5857
const tagsStore = useTagsStore();
5958
const snackbar = useSnackbar();
6059
6160
const showDialog = ref(false);
62-
const inputTags = ref<string>("");
63-
const tagsError = ref("");
64-
65-
const tenant = computed(() => localStorage.getItem("tenant"));
66-
67-
const tagsHasLessThan3Characters = computed(() => inputTags.value.length < 3);
68-
69-
watch(inputTags, () => {
70-
if (inputTags.value.length > 255) {
71-
tagsError.value = "The maximum length is 255 characters";
72-
} else if (tagsHasLessThan3Characters.value) {
73-
tagsError.value = "The minimum length is 3 characters";
74-
} else {
75-
tagsError.value = "";
76-
}
77-
});
78-
79-
const confirmDisabled = computed(() => !inputTags.value || !!tagsError.value);
61+
const tagInput = ref<string>("");
62+
const tagError = ref("");
63+
const confirmDisabled = computed(() => !tagInput.value || !!tagError.value);
64+
65+
const validateTagInput = () => {
66+
const inputLength = tagInput.value.length;
67+
if (inputLength > 255) tagError.value = "The maximum length is 255 characters";
68+
else if (inputLength < 3) tagError.value = "The minimum length is 3 characters";
69+
else tagError.value = "";
70+
};
8071
8172
const open = () => {
8273
showDialog.value = true;
83-
inputTags.value = props.tagName;
74+
tagInput.value = props.tagName;
8475
};
8576
8677
const close = () => {
8778
showDialog.value = false;
88-
inputTags.value = "";
79+
tagInput.value = "";
8980
};
9081
9182
const update = () => {
@@ -94,14 +85,13 @@ const update = () => {
9485
};
9586
9687
const edit = async () => {
97-
if (tagsError.value) return;
88+
if (tagError.value) return;
9889
9990
try {
100-
await tagsStore.editTag({
101-
tenant: tenant.value || "",
102-
currentName: props.tagName,
103-
newName: { name: inputTags.value },
104-
});
91+
await tagsStore.updateTag(
92+
props.tagName,
93+
{ name: tagInput.value },
94+
);
10595
10696
snackbar.showSuccess("Tag updated successfully.");
10797
update();
@@ -110,6 +100,4 @@ const edit = async () => {
110100
handleError(error);
111101
}
112102
};
113-
114-
defineExpose({ inputTags });
115103
</script>

0 commit comments

Comments
 (0)