فهرست منبع

feat: add UnitMultiSelect component

Multi-select with chips for associating users with multiple units
ebagabee 2 هفته پیش
والد
کامیت
e752bd8ecc
1فایلهای تغییر یافته به همراه87 افزوده شده و 0 حذف شده
  1. 87 0
      src/components/selects/UnitMultiSelect.vue

+ 87 - 0
src/components/selects/UnitMultiSelect.vue

@@ -0,0 +1,87 @@
+<template>
+  <q-select
+    v-model="selectedUnits"
+    v-bind="$attrs"
+    multiple
+    use-chips
+    use-input
+    fill-input
+    clearable
+    :options="filteredOptions"
+    :loading="isLoading"
+    :label="label"
+    :bg-color="bgColor"
+    option-value="value"
+    option-label="label"
+    @filter="filterFn"
+  >
+    <template #no-option>
+      <q-item>
+        <q-item-section class="text-grey">
+          Nenhum registro encontrado
+        </q-item-section>
+      </q-item>
+    </template>
+  </q-select>
+</template>
+
+<script setup>
+import { onMounted, ref, watch } from "vue";
+import { getUnitsForSelect } from "src/api/unit";
+
+const { label, initialIds, bgColor } = defineProps({
+  label: { type: String, default: "Unidades" },
+  initialIds: { type: Array, default: () => [] },
+  bgColor: { type: String, default: "white" },
+});
+
+const selectedUnits = defineModel({ type: Array, default: () => [] });
+const unitOptions = ref([]);
+const filteredOptions = ref([]);
+const isLoading = ref(true);
+
+const selectUnitsByIds = (ids) => {
+  if (!ids?.length) return;
+  selectedUnits.value = unitOptions.value.filter((o) => ids.includes(o.value));
+};
+
+const filterFn = (val, update) => {
+  update(() => {
+    if (val === "") {
+      filteredOptions.value = unitOptions.value;
+    } else {
+      const needle = val.toLowerCase();
+      filteredOptions.value = unitOptions.value.filter((v) =>
+        v.label.toLowerCase().includes(needle),
+      );
+    }
+  });
+};
+
+onMounted(async () => {
+  try {
+    const response = await getUnitsForSelect();
+    unitOptions.value = response.map((unit) => ({
+      label: unit.fantasy_name,
+      value: unit.id,
+    }));
+    filteredOptions.value = unitOptions.value;
+    if (initialIds?.length > 0) selectUnitsByIds(initialIds);
+  } catch (error) {
+    console.error("Failed to load units:", error);
+  } finally {
+    isLoading.value = false;
+  }
+});
+
+watch(
+  () => initialIds,
+  (newIds) => {
+    if (newIds?.length > 0 && unitOptions.value.length > 0) {
+      selectUnitsByIds(newIds);
+    }
+  },
+);
+
+defineExpose({ selectUnitsByIds });
+</script>