Added easy label creation to multiselect (#425)

* feat: added easy label creation to multiselect, also fixed webhooks in dev mode

* fix: add missing translation
This commit is contained in:
Tonya
2025-01-03 19:29:48 +00:00
committed by GitHub
parent 1638e35da3
commit 2b4ad9356d
2 changed files with 37 additions and 20 deletions

View File

@@ -5,8 +5,8 @@
</label>
<div class="dropdown dropdown-top sm:dropdown-end">
<div tabindex="0" class="flex min-h-[48px] w-full flex-wrap gap-2 rounded-lg border border-gray-400 p-4">
<span v-for="itm in value" :key="name != '' ? itm[name] : itm" class="badge">
{{ name != "" ? itm[name] : itm }}
<span v-for="itm in value" :key="itm.id" class="badge">
{{ itm.name }}
</span>
<button
v-if="value.length > 0"
@@ -20,7 +20,7 @@
<div
tabindex="0"
style="display: inline"
class="dropdown-content menu z-[9999] mb-1 w-full rounded border border-gray-400 bg-base-100 shadow"
class="dropdown-content menu bg-base-100 z-[9999] mb-1 w-full rounded border border-gray-400 shadow"
>
<div class="m-2">
<input v-model="search" placeholder="Search…" class="input input-bordered input-sm w-full" />
@@ -30,13 +30,16 @@
v-for="(obj, idx) in filteredItems"
:key="idx"
:class="{
bordered: selected.includes(obj[props.uniqueField]),
bordered: selected.includes(obj.id),
}"
>
<button type="button" @click="toggle(obj[props.uniqueField])">
{{ name != "" ? obj[name] : obj }}
<button type="button" @click="toggle(obj.id)">
{{ obj.name }}
</button>
</li>
<li v-if="!filteredItems.some(itm => itm.name === search) && search.length > 0">
<button type="button" @click="createAndAdd(search)">{{ $t("global.create") }} {{ search }}</button>
</li>
</ul>
</div>
</div>
@@ -60,14 +63,6 @@
type: Array as () => any[],
required: true,
},
name: {
type: String,
default: "name",
},
uniqueField: {
type: String,
default: "id",
},
selectFirst: {
type: Boolean,
default: false,
@@ -84,7 +79,7 @@
}
return props.items.filter(item => {
return item[props.name].toLowerCase().includes(search.value.toLowerCase());
return item.name.toLowerCase().includes(search.value.toLowerCase());
});
});
@@ -93,15 +88,33 @@
}
const selected = computed<string[]>(() => {
return value.value.map(itm => itm[props.uniqueField]);
return value.value.map(itm => itm.id);
});
function toggle(uniqueField: string) {
const item = props.items.find(itm => itm[props.uniqueField] === uniqueField);
if (selected.value.includes(item[props.uniqueField])) {
value.value = value.value.filter(itm => itm[props.uniqueField] !== item[props.uniqueField]);
const item = props.items.find(itm => itm.id === uniqueField);
if (selected.value.includes(item.id)) {
value.value = value.value.filter(itm => itm.id !== item.id);
} else {
value.value = [...value.value, item];
}
}
const api = useUserApi();
const toast = useNotifier();
async function createAndAdd(name: string) {
const { error, data } = await api.labels.create({
name,
color: "", // Future!
description: "",
});
if (error) {
console.error(error);
toast.error(`Failed to create label: ${name}`);
} else {
value.value = [...value.value, data];
}
}
</script>