Skip to content

Commit 21ccc80

Browse files
committed
refactor(ui): handle new tags objects
This commit refactor all tags object with new handling capabilities, using pagination on lists and a new refactored TagFormUpdate on the device and container associated tags.
1 parent bbaa709 commit 21ccc80

30 files changed

+2572
-2483
lines changed

ui/src/api/client/api.ts

+667-2,057
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.
+76-23
Original file line numberDiff line numberDiff line change
@@ -1,44 +1,97 @@
11
<template>
2+
<TagCreate v-model="createDialog" @update="refreshTagList()" />
23
<v-container fluid>
3-
<PrivateKeyAdd v-model="privateKeyAdd" @update="getPrivateKeys" />
44
<v-card
55
variant="flat"
66
class="bg-transparent"
77
data-test="account-profile-card"
88
>
9-
<v-card-item>
10-
<v-list-item
11-
class="pa-0 ma-0 mb-2"
12-
data-test="profile-header"
13-
>
14-
<template v-slot:title>
15-
<h1>Tags</h1>
16-
</template>
17-
<template v-slot:subtitle>
18-
<span data-test="profile-subtitle">Manage your device and connector tags</span>
19-
</template>
20-
</v-list-item>
21-
</v-card-item>
22-
<TagList />
9+
10+
<v-row cols="12">
11+
<v-col cols="3">
12+
<v-card-item class="pa-0 ma-0 mb-2">
13+
<v-list-item data-test="profile-header">
14+
<template v-slot:title>
15+
<h1>Tags</h1>
16+
</template>
17+
<template v-slot:subtitle>
18+
<span data-test="profile-subtitle">Manage your device and connector tags</span>
19+
</template>
20+
</v-list-item>
21+
</v-card-item>
22+
</v-col>
23+
<v-col cols="6">
24+
<v-text-field
25+
label="Search by Tag Name"
26+
variant="outlined"
27+
color="primary"
28+
single-line
29+
hide-details
30+
v-model.trim="filter"
31+
v-on:keyup="searchTags"
32+
prepend-inner-icon="mdi-magnify"
33+
density="compact"
34+
data-test="search-text"
35+
/>
36+
</v-col>
37+
<v-col cols="3" class="d-flex justify-end">
38+
<v-btn
39+
@click="openCreate"
40+
color="primary"
41+
variant="text"
42+
class="bg-secondary border"
43+
data-test="tag-create-button"
44+
>
45+
Create Tag
46+
</v-btn>
47+
</v-col>
48+
49+
</v-row>
50+
<TagList ref="tagListRef" />
2351
</v-card>
2452
</v-container>
2553
</template>
2654

2755
<script setup lang="ts">
28-
import { ref } from "vue";
29-
import PrivateKeyAdd from "../PrivateKeys/PrivateKeyAdd.vue";
56+
import { computed, ref } from "vue";
3057
import TagList from "../Tags/TagList.vue";
58+
import TagCreate from "../Tags/TagCreate.vue";
3159
import { useStore } from "@/store";
32-
import handleError from "@/utils/handleError";
3360
3461
const store = useStore();
35-
const privateKeyAdd = ref(false);
62+
const tagListRef = ref<InstanceType<typeof TagList> | null>(null);
63+
const createDialog = ref(false);
64+
const filter = ref("");
65+
const tenant = computed(() => localStorage.getItem("tenant"));
66+
67+
const searchTags = () => {
68+
let encodedFilter = "";
69+
70+
if (filter.value) {
71+
const filterToEncodeBase64 = [
72+
{
73+
type: "property",
74+
params: { name: "name", operator: "contains", value: filter.value },
75+
},
76+
];
77+
encodedFilter = btoa(JSON.stringify(filterToEncodeBase64));
78+
}
3679
37-
const getPrivateKeys = async () => {
3880
try {
39-
await store.dispatch("privateKey/fetch");
40-
} catch (error: unknown) {
41-
handleError(error);
81+
store.dispatch("tags/search", {
82+
tenant: tenant.value,
83+
filter: encodedFilter,
84+
});
85+
} catch {
86+
store.dispatch("snackbar/showSnackbarErrorDefault");
4287
}
4388
};
89+
90+
const openCreate = () => {
91+
createDialog.value = true;
92+
};
93+
94+
const refreshTagList = () => {
95+
tagListRef.value?.refresh();
96+
};
4497
</script>

ui/src/components/Tables/DeviceTable.vue

+4-4
Original file line numberDiff line numberDiff line change
@@ -63,7 +63,7 @@
6363
v-for="(tag, index) in item.tags"
6464
:key="index"
6565
location="bottom"
66-
:disabled="!showTag(tag)"
66+
:disabled="!showTag(tag.name)"
6767
>
6868
<template #activator="{ props }">
6969
<v-chip
@@ -73,12 +73,12 @@
7373
class="mr-1"
7474
data-test="tag-chip"
7575
>
76-
{{ displayOnlyTenCharacters(tag) }}
76+
{{ displayOnlyTenCharacters(tag.name) }}
7777
</v-chip>
7878
</template>
7979

80-
<span v-if="showTag(tag)">
81-
{{ tag }}
80+
<span v-if="showTag(tag.name)">
81+
{{ tag.name }}
8282
</span>
8383
</v-tooltip>
8484
</div>

ui/src/components/Tags/TagCreate.vue

+99
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,99 @@
1+
<template>
2+
<v-dialog v-model="showDialog" min-width="300" max-width="600">
3+
<v-card class="bg-v-theme-surface">
4+
<v-card-title class="text-h5 pa-4 bg-primary"> Create Tag </v-card-title>
5+
<v-divider />
6+
7+
<v-card-text class="mt-4 mb-0 pb-1">
8+
<v-text-field
9+
v-model="inputTags"
10+
label="Tag name"
11+
:error-messages="tagsError"
12+
required
13+
variant="underlined"
14+
data-test="tag-field"
15+
/>
16+
</v-card-text>
17+
18+
<v-card-actions>
19+
<v-spacer />
20+
<v-btn variant="text" data-test="close-btn" @click="close()">
21+
Close
22+
</v-btn>
23+
24+
<v-btn
25+
color="primary"
26+
variant="text"
27+
data-test="create-btn"
28+
@click="create()"
29+
>
30+
Create
31+
</v-btn>
32+
</v-card-actions>
33+
</v-card>
34+
</v-dialog>
35+
</template>
36+
37+
<script setup lang="ts">
38+
import { ref, computed, watch } from "vue";
39+
import { useStore } from "../../store";
40+
import {
41+
INotificationsError,
42+
INotificationsSuccess,
43+
} from "../../interfaces/INotifications";
44+
import handleError from "@/utils/handleError";
45+
46+
const emit = defineEmits(["update"]);
47+
const store = useStore();
48+
const showDialog = defineModel({ default: false });
49+
50+
const inputTags = ref<string>("");
51+
const tagsError = ref("");
52+
const tagsHasLessThan3Characters = computed(() => inputTags.value.length < 3);
53+
const tenant = computed(() => localStorage.getItem("tenant"));
54+
55+
watch(inputTags, () => {
56+
if (inputTags.value.length > 255) {
57+
tagsError.value = "Maximum of 3 tags";
58+
} else if (tagsHasLessThan3Characters.value) {
59+
tagsError.value = "The minimum length is 3 characters";
60+
} else {
61+
tagsError.value = "";
62+
}
63+
});
64+
65+
const close = () => {
66+
inputTags.value = "";
67+
showDialog.value = false;
68+
};
69+
70+
const update = () => {
71+
emit("update");
72+
close();
73+
};
74+
75+
const create = async () => {
76+
if (!tagsError.value) {
77+
try {
78+
await store.dispatch("tags/createTag", {
79+
tenant: tenant.value,
80+
name: inputTags.value,
81+
});
82+
83+
update();
84+
store.dispatch(
85+
"snackbar/showSnackbarSuccessAction",
86+
INotificationsSuccess.deviceTagCreate,
87+
);
88+
} catch (error: unknown) {
89+
store.dispatch(
90+
"snackbar/showSnackbarErrorAction",
91+
INotificationsError.deviceTagCreate,
92+
);
93+
handleError(error);
94+
}
95+
}
96+
};
97+
98+
defineExpose({ inputTags, showDialog });
99+
</script>

ui/src/components/Tags/TagEdit.vue

+11-5
Original file line numberDiff line numberDiff line change
@@ -61,7 +61,7 @@ import {
6161
import handleError from "@/utils/handleError";
6262
6363
const props = defineProps({
64-
tag: {
64+
tagName: {
6565
type: String,
6666
required: true,
6767
},
@@ -70,13 +70,15 @@ const props = defineProps({
7070
default: false,
7171
},
7272
});
73+
7374
const emit = defineEmits(["update"]);
7475
const store = useStore();
7576
const showDialog = ref(false);
7677
7778
const inputTags = ref<string>("");
7879
const tagsError = ref("");
7980
const tagsHasLessThan3Characters = computed(() => inputTags.value.length < 3);
81+
const tenant = computed(() => localStorage.getItem("tenant"));
8082
8183
watch(inputTags, () => {
8284
if (inputTags.value.length > 255) {
@@ -89,12 +91,13 @@ watch(inputTags, () => {
8991
});
9092
9193
const open = () => {
92-
inputTags.value = props.tag;
9394
showDialog.value = true;
95+
inputTags.value = props.tagName;
9496
};
9597
9698
const close = () => {
9799
showDialog.value = false;
100+
inputTags.value = "";
98101
};
99102
100103
const update = () => {
@@ -105,9 +108,12 @@ const update = () => {
105108
const edit = async () => {
106109
if (!tagsError.value) {
107110
try {
108-
await store.dispatch("tags/edit", {
109-
oldTag: props.tag,
110-
newTag: inputTags.value,
111+
await store.dispatch("tags/editTag", {
112+
tenant: tenant.value,
113+
currentName: props.tagName,
114+
newName: {
115+
name: inputTags.value,
116+
},
111117
});
112118
113119
update();

0 commit comments

Comments
 (0)