PositionSelect.vue 1.5 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768
  1. <template>
  2. <DefaultSelect
  3. v-model="selected"
  4. v-bind="$attrs"
  5. use-input
  6. hide-selected
  7. fill-input
  8. clearable
  9. :options="filteredOptions"
  10. :label
  11. :loading
  12. :placeholder
  13. @filter="filterFn"
  14. >
  15. <template #no-option>
  16. <q-item>
  17. <q-item-section class="text-grey">
  18. {{ $t("http.errors.no_records_found") }}
  19. </q-item-section>
  20. </q-item>
  21. </template>
  22. </DefaultSelect>
  23. </template>
  24. <script setup>
  25. import { ref, onMounted } from "vue";
  26. import { getPositions } from "src/api/position";
  27. import { normalizeString } from "src/helpers/utils";
  28. import { useI18n } from "vue-i18n";
  29. import DefaultSelect from "src/components/defaults/DefaultSelect.vue";
  30. const { label, placeholder } = defineProps({
  31. label: {
  32. type: String,
  33. default: () => useI18n().t("associado.position"),
  34. },
  35. placeholder: {
  36. type: String,
  37. default: () => useI18n().t("common.actions.search"),
  38. },
  39. });
  40. const selected = defineModel({ type: Object });
  41. const loading = ref(true);
  42. const baseOptions = ref([]);
  43. const filteredOptions = ref([]);
  44. const filterFn = (val, update) => {
  45. const needle = normalizeString(val);
  46. filteredOptions.value = baseOptions.value.filter((v) =>
  47. normalizeString(v.label).includes(needle),
  48. );
  49. update();
  50. };
  51. onMounted(async () => {
  52. try {
  53. const items = await getPositions();
  54. baseOptions.value = items.map((p) => ({ label: p.name, value: p.id }));
  55. filteredOptions.value = baseOptions.value;
  56. } catch (e) {
  57. console.error(e);
  58. } finally {
  59. loading.value = false;
  60. }
  61. });
  62. </script>