Skip to content

refactor(ui): handle new tags objects #4632

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2,102 changes: 463 additions & 1,639 deletions ui/src/api/client/api.ts

Large diffs are not rendered by default.

99 changes: 76 additions & 23 deletions ui/src/components/Setting/SettingTags.vue
Original file line number Diff line number Diff line change
@@ -1,44 +1,97 @@
<template>
<TagCreate v-model="createDialog" @update="refreshTagList()" />
<v-container fluid>
<PrivateKeyAdd v-model="privateKeyAdd" @update="getPrivateKeys" />
<v-card
variant="flat"
class="bg-transparent"
data-test="account-profile-card"
>
<v-card-item>
<v-list-item
class="pa-0 ma-0 mb-2"
data-test="profile-header"
>
<template v-slot:title>
<h1>Tags</h1>
</template>
<template v-slot:subtitle>
<span data-test="profile-subtitle">Manage your device and connector tags</span>
</template>
</v-list-item>
</v-card-item>
<TagList />

<v-row cols="12">
<v-col cols="3">
<v-card-item class="pa-0 ma-0 mb-2">
<v-list-item data-test="profile-header">
<template v-slot:title>
<h1>Tags</h1>
</template>
<template v-slot:subtitle>
<span data-test="profile-subtitle">Manage your device and connector tags</span>
</template>
</v-list-item>
</v-card-item>
</v-col>
<v-col cols="6">
<v-text-field
label="Search by Tag Name"
variant="outlined"
color="primary"
single-line
hide-details
v-model.trim="filter"
v-on:keyup="searchTags"
prepend-inner-icon="mdi-magnify"
density="compact"
data-test="search-text"
/>
</v-col>
<v-col cols="3" class="d-flex justify-end">
<v-btn
@click="openCreate"
color="primary"
variant="text"
class="bg-secondary border"
data-test="tag-create-button"
>
Create Tag
</v-btn>
</v-col>

</v-row>
<TagList ref="tagListRef" />
</v-card>
</v-container>
</template>

<script setup lang="ts">
import { ref } from "vue";
import PrivateKeyAdd from "../PrivateKeys/PrivateKeyAdd.vue";
import { computed, ref } from "vue";
import TagList from "../Tags/TagList.vue";
import TagCreate from "../Tags/TagCreate.vue";
import { useStore } from "@/store";
import handleError from "@/utils/handleError";

const store = useStore();
const privateKeyAdd = ref(false);
const tagListRef = ref<InstanceType<typeof TagList> | null>(null);
const createDialog = ref(false);
const filter = ref("");
const tenant = computed(() => localStorage.getItem("tenant"));

const searchTags = () => {
let encodedFilter = "";

if (filter.value) {
const filterToEncodeBase64 = [
{
type: "property",
params: { name: "name", operator: "contains", value: filter.value },
},
];
encodedFilter = btoa(JSON.stringify(filterToEncodeBase64));
}

const getPrivateKeys = async () => {
try {
await store.dispatch("privateKey/fetch");
} catch (error: unknown) {
handleError(error);
store.dispatch("tags/search", {
tenant: tenant.value,
filter: encodedFilter,
});
} catch {
store.dispatch("snackbar/showSnackbarErrorDefault");
}
};

const openCreate = () => {
createDialog.value = true;
};

const refreshTagList = () => {
tagListRef.value?.refresh();
};
</script>
8 changes: 4 additions & 4 deletions ui/src/components/Tables/DeviceTable.vue
Original file line number Diff line number Diff line change
@@ -62,7 +62,7 @@
v-for="(tag, index) in item.tags"
:key="index"
location="bottom"
:disabled="!showTag(tag)"
:disabled="!showTag(tag.name)"
>
<template #activator="{ props }">
<v-chip
@@ -71,12 +71,12 @@
class="mr-1"
data-test="tag-chip"
>
{{ displayOnlyTenCharacters(tag) }}
{{ displayOnlyTenCharacters(tag.name) }}
</v-chip>
</template>

<span v-if="showTag(tag)">
{{ tag }}
<span v-if="showTag(tag.name)">
{{ tag.name }}
</span>
</v-tooltip>
</div>
91 changes: 91 additions & 0 deletions ui/src/components/Tags/TagCreate.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,91 @@
<template>
<v-dialog v-model="showDialog" min-width="300" max-width="600">
<v-card class="bg-v-theme-surface">
<v-card-title class="text-h5 pa-4 bg-primary"> Create Tag </v-card-title>
<v-divider />

<v-card-text class="mt-4 mb-0 pb-1">
<v-text-field
v-model="inputTags"
label="Tag name"
:error-messages="tagsError"
required
variant="underlined"
data-test="tag-field"
/>
</v-card-text>

<v-card-actions>
<v-spacer />
<v-btn variant="text" data-test="close-btn" @click="close()">
Close
</v-btn>

<v-btn
color="primary"
variant="text"
data-test="create-btn"
@click="create()"
>
Create
</v-btn>
</v-card-actions>
</v-card>
</v-dialog>
</template>

<script setup lang="ts">
import { ref, computed, watch } from "vue";
import { useStore } from "../../store";
import handleError from "@/utils/handleError";
import useSnackbar from "@/helpers/snackbar";

const emit = defineEmits(["update"]);
const store = useStore();
const snackbar = useSnackbar();
const showDialog = defineModel({ default: false });

const inputTags = ref<string>("");
const tagsError = ref("");
const tagsHasLessThan3Characters = computed(() => inputTags.value.length < 3);
const tenant = computed(() => localStorage.getItem("tenant"));

watch(inputTags, () => {
if (inputTags.value.length > 255) {
tagsError.value = "Maximum of 3 tags";
} else if (tagsHasLessThan3Characters.value) {
tagsError.value = "The minimum length is 3 characters";
} else {
tagsError.value = "";
}
});

const close = () => {
inputTags.value = "";
showDialog.value = false;
};

const update = () => {
emit("update");
close();
};

const create = async () => {
if (!tagsError.value) {
try {
await store.dispatch("tags/createTag", {
tenant: tenant.value,
name: inputTags.value,
});

update();
snackbar.showSuccess("Successfully created tag");
} catch (error: unknown) {
snackbar.showError("Failed to create tag.");
handleError(error);
}
}
};

defineExpose({ inputTags, showDialog });
</script>
16 changes: 11 additions & 5 deletions ui/src/components/Tags/TagEdit.vue
Original file line number Diff line number Diff line change
@@ -58,7 +58,7 @@ import handleError from "@/utils/handleError";
import useSnackbar from "@/helpers/snackbar";

const props = defineProps({
tag: {
tagName: {
type: String,
required: true,
},
@@ -67,6 +67,7 @@ const props = defineProps({
default: false,
},
});

const emit = defineEmits(["update"]);
const store = useStore();
const snackbar = useSnackbar();
@@ -75,6 +76,7 @@ const showDialog = ref(false);
const inputTags = ref<string>("");
const tagsError = ref("");
const tagsHasLessThan3Characters = computed(() => inputTags.value.length < 3);
const tenant = computed(() => localStorage.getItem("tenant"));

watch(inputTags, () => {
if (inputTags.value.length > 255) {
@@ -87,12 +89,13 @@ watch(inputTags, () => {
});

const open = () => {
inputTags.value = props.tag;
showDialog.value = true;
inputTags.value = props.tagName;
};

const close = () => {
showDialog.value = false;
inputTags.value = "";
};

const update = () => {
@@ -103,9 +106,12 @@ const update = () => {
const edit = async () => {
if (!tagsError.value) {
try {
await store.dispatch("tags/edit", {
oldTag: props.tag,
newTag: inputTags.value,
await store.dispatch("tags/editTag", {
tenant: tenant.value,
currentName: props.tagName,
newName: {
name: inputTags.value,
},
});

update();
Loading
Oops, something went wrong.