next/components/findUser.vue

76 lines
1.7 KiB
Vue
Raw Normal View History

<script lang="ts" setup>
import { debounce } from "lodash-es";
import { useField } from "vee-validate";
import { IUser } from "@models/user";
const props = defineProps<{
fieldName: string;
multi: boolean;
initialOption:
| number
| {
label: string;
value: number;
}
| null;
}>();
let initO;
if (typeof props.initialOption == "number") {
const { data } = await useApiFetch<IUser>(`/user/${props.initialOption}`);
initO = {
label: data.value.username,
value: data.value._id,
};
} else if (typeof props.initialOption == "object") {
initO = props.initialOption;
}
const state = reactive<{
data: { value: number; label: string }[];
fetching: boolean;
}>({
data: props.initialOption ? [initO] : [],
fetching: false,
});
let fieldo = useField<number | number[]>(props.fieldName, undefined, {
// @ts-ignore
initialValue: initO?.value || null,
});
const { value, errorMessage, name, setValue } = fieldo;
const fetchUsers = debounce((value) => {
state.fetching = true;
useApiFetch<{ _id: number; username: string }[]>(`/all-users`, {
query: {
name: value,
},
}).then(({ data }) => {
const blip = data.value?.map((a) => ({
label: a.username,
value: a._id,
}));
state.data = blip!;
state.fetching = false;
});
}, 750);
</script>
<template>
<a-select
option-filter-prop="label"
:show-search="true"
@search="fetchUsers"
:filter-option="true"
style="width: 100%"
placeholder="Find a user..."
:mode="multi ? 'multiple' : undefined"
:options="state.data"
v-model:value="value"
:allow-clear="true"
>
<template v-if="state.fetching" #notFoundContent>
<a-spin size="small" />
</template>
</a-select>
</template>