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> </label>
<div class="dropdown dropdown-top sm:dropdown-end"> <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"> <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"> <span v-for="itm in value" :key="itm.id" class="badge">
{{ name != "" ? itm[name] : itm }} {{ itm.name }}
</span> </span>
<button <button
v-if="value.length > 0" v-if="value.length > 0"
@@ -20,7 +20,7 @@
<div <div
tabindex="0" tabindex="0"
style="display: inline" 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"> <div class="m-2">
<input v-model="search" placeholder="Search…" class="input input-bordered input-sm w-full" /> <input v-model="search" placeholder="Search…" class="input input-bordered input-sm w-full" />
@@ -30,13 +30,16 @@
v-for="(obj, idx) in filteredItems" v-for="(obj, idx) in filteredItems"
:key="idx" :key="idx"
:class="{ :class="{
bordered: selected.includes(obj[props.uniqueField]), bordered: selected.includes(obj.id),
}" }"
> >
<button type="button" @click="toggle(obj[props.uniqueField])"> <button type="button" @click="toggle(obj.id)">
{{ name != "" ? obj[name] : obj }} {{ obj.name }}
</button> </button>
</li> </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> </ul>
</div> </div>
</div> </div>
@@ -60,14 +63,6 @@
type: Array as () => any[], type: Array as () => any[],
required: true, required: true,
}, },
name: {
type: String,
default: "name",
},
uniqueField: {
type: String,
default: "id",
},
selectFirst: { selectFirst: {
type: Boolean, type: Boolean,
default: false, default: false,
@@ -84,7 +79,7 @@
} }
return props.items.filter(item => { 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[]>(() => { const selected = computed<string[]>(() => {
return value.value.map(itm => itm[props.uniqueField]); return value.value.map(itm => itm.id);
}); });
function toggle(uniqueField: string) { function toggle(uniqueField: string) {
const item = props.items.find(itm => itm[props.uniqueField] === uniqueField); const item = props.items.find(itm => itm.id === uniqueField);
if (selected.value.includes(item[props.uniqueField])) { if (selected.value.includes(item.id)) {
value.value = value.value.filter(itm => itm[props.uniqueField] !== item[props.uniqueField]); value.value = value.value.filter(itm => itm.id !== item.id);
} else { } else {
value.value = [...value.value, item]; 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> </script>

View File

@@ -18,7 +18,11 @@ function connect(onmessage: (m: EventMessage) => void) {
protocol = "wss"; protocol = "wss";
} }
const ws = new WebSocket(`${protocol}://${window.location.host}/api/v1/ws/events`); const dev = import.meta.dev;
const host = dev ? window.location.host.replace("3000", "7745") : window.location.host;
const ws = new WebSocket(`${protocol}://${host}/api/v1/ws/events`);
ws.onopen = () => { ws.onopen = () => {
console.debug("connected to server"); console.debug("connected to server");