Skip to content
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

Added easy label creation to multiselect #425

Merged
merged 2 commits into from
Jan 3, 2025
Merged
Show file tree
Hide file tree
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
51 changes: 32 additions & 19 deletions frontend/components/Form/Multiselect.vue
Original file line number Diff line number Diff line change
Expand Up @@ -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"
Expand All @@ -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" />
Expand All @@ -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>
Expand All @@ -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,
Expand All @@ -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());
});
});

Expand All @@ -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>
6 changes: 5 additions & 1 deletion frontend/composables/use-server-events.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,11 @@ function connect(onmessage: (m: EventMessage) => void) {
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 = () => {
console.debug("connected to server");
Expand Down
Loading