search select component improvements

This commit is contained in:
Julian Krauser 2025-06-15 22:04:41 +02:00
parent fe0f31ce6b
commit e7078960ba
7 changed files with 146 additions and 30 deletions

View file

@ -32,12 +32,12 @@
<span class="font-normal block truncate">suche</span> <span class="font-normal block truncate">suche</span>
</li> </li>
</ComboboxOption> </ComboboxOption>
<ComboboxOption v-else-if="filtered.length === 0 && query == ''" as="template" disabled> <ComboboxOption v-else-if="available.length === 0" as="template" disabled>
<li class="text-text relative cursor-default select-none py-2 pl-3 pr-4"> <li class="text-text relative cursor-default select-none py-2 pl-3 pr-4">
<span class="font-normal block truncate">tippe, um zu suchen...</span> <span class="font-normal block truncate">tippe, um zu suchen...</span>
</li> </li>
</ComboboxOption> </ComboboxOption>
<ComboboxOption v-else-if="filtered.length === 0" as="template" disabled> <ComboboxOption v-else-if="available.length === 0 && query != ''" as="template" disabled>
<li class="text-text relative cursor-default select-none py-2 pl-3 pr-4"> <li class="text-text relative cursor-default select-none py-2 pl-3 pr-4">
<span class="font-normal block truncate">Keine Auswahl gefunden.</span> <span class="font-normal block truncate">Keine Auswahl gefunden.</span>
</li> </li>
@ -45,7 +45,7 @@
<ComboboxOption <ComboboxOption
v-if="!(loading || deferingSearch)" v-if="!(loading || deferingSearch)"
v-for="equipment in filtered" v-for="equipment in available"
as="template" as="template"
:key="equipment.id" :key="equipment.id"
:value="equipment.id" :value="equipment.id"
@ -137,11 +137,15 @@ export default defineComponent({
deferingSearch: false as boolean, deferingSearch: false as boolean,
timer: undefined as any, timer: undefined as any,
query: "" as string, query: "" as string,
all: [] as Array<EquipmentViewModel>,
filtered: [] as Array<EquipmentViewModel>, filtered: [] as Array<EquipmentViewModel>,
chosen: undefined as undefined | EquipmentViewModel, chosen: undefined as undefined | EquipmentViewModel,
}; };
}, },
computed: { computed: {
available() {
return this.query == "" ? this.all : this.filtered;
},
selected: { selected: {
get() { get() {
return this.modelValue; return this.modelValue;
@ -154,10 +158,22 @@ export default defineComponent({
}, },
mounted() { mounted() {
this.loadEquipmentInitial(); this.loadEquipmentInitial();
this.preloadAll();
}, },
methods: { methods: {
...mapActions(useEquipmentStore, ["searchEquipments", "fetchEquipmentById"]), ...mapActions(useEquipmentStore, ["searchEquipments", "fetchEquipmentById", "getAllEquipments"]),
...mapActions(useModalStore, ["openModal"]), ...mapActions(useModalStore, ["openModal"]),
preloadAll() {
this.loading = true;
this.getAllEquipments()
.then((res) => {
this.all = res.data;
})
.catch((err) => {})
.finally(() => {
this.loading = false;
});
},
search() { search() {
this.filtered = []; this.filtered = [];
if (this.query == "") return; if (this.query == "") return;

View file

@ -26,12 +26,12 @@
<span class="font-normal block truncate">suche</span> <span class="font-normal block truncate">suche</span>
</li> </li>
</ComboboxOption> </ComboboxOption>
<ComboboxOption v-else-if="filtered.length === 0 && query == ''" as="template" disabled> <ComboboxOption v-else-if="available.length === 0" as="template" disabled>
<li class="text-text relative cursor-default select-none py-2 pl-3 pr-4"> <li class="text-text relative cursor-default select-none py-2 pl-3 pr-4">
<span class="font-normal block truncate">tippe, um zu suchen...</span> <span class="font-normal block truncate">tippe, um zu suchen...</span>
</li> </li>
</ComboboxOption> </ComboboxOption>
<ComboboxOption v-else-if="filtered.length === 0" as="template" disabled> <ComboboxOption v-else-if="available.length === 0 && query != ''" as="template" disabled>
<li class="text-text relative cursor-default select-none py-2 pl-3 pr-4"> <li class="text-text relative cursor-default select-none py-2 pl-3 pr-4">
<span class="font-normal block truncate">Keine Auswahl gefunden.</span> <span class="font-normal block truncate">Keine Auswahl gefunden.</span>
</li> </li>
@ -39,7 +39,7 @@
<ComboboxOption <ComboboxOption
v-if="!(loading || deferingSearch)" v-if="!(loading || deferingSearch)"
v-for="equipmentType in filtered" v-for="equipmentType in available"
as="template" as="template"
:key="equipmentType.id" :key="equipmentType.id"
:value="equipmentType.id" :value="equipmentType.id"
@ -125,11 +125,15 @@ export default defineComponent({
deferingSearch: false as boolean, deferingSearch: false as boolean,
timer: undefined as any, timer: undefined as any,
query: "" as string, query: "" as string,
all: [] as Array<EquipmentTypeViewModel>,
filtered: [] as Array<EquipmentTypeViewModel>, filtered: [] as Array<EquipmentTypeViewModel>,
chosen: undefined as undefined | EquipmentTypeViewModel, chosen: undefined as undefined | EquipmentTypeViewModel,
}; };
}, },
computed: { computed: {
available() {
return this.query == "" ? this.all : this.filtered;
},
selected: { selected: {
get() { get() {
return this.modelValue; return this.modelValue;
@ -142,9 +146,21 @@ export default defineComponent({
}, },
mounted() { mounted() {
this.loadEquipmentTypeInitial(); this.loadEquipmentTypeInitial();
this.preloadAll();
}, },
methods: { methods: {
...mapActions(useEquipmentTypeStore, ["searchEquipmentTypes", "fetchEquipmentTypeById"]), ...mapActions(useEquipmentTypeStore, ["searchEquipmentTypes", "fetchEquipmentTypeById", "getAllEquipmentTypes"]),
preloadAll() {
this.loading = true;
this.getAllEquipmentTypes()
.then((res) => {
this.all = res.data;
})
.catch((err) => {})
.finally(() => {
this.loading = false;
});
},
search() { search() {
this.filtered = []; this.filtered = [];
if (this.query == "") return; if (this.query == "") return;

View file

@ -26,12 +26,12 @@
<span class="font-normal block truncate">suche</span> <span class="font-normal block truncate">suche</span>
</li> </li>
</ComboboxOption> </ComboboxOption>
<ComboboxOption v-else-if="filtered.length === 0 && query == ''" as="template" disabled> <ComboboxOption v-else-if="available.length === 0" as="template" disabled>
<li class="text-text relative cursor-default select-none py-2 pl-3 pr-4"> <li class="text-text relative cursor-default select-none py-2 pl-3 pr-4">
<span class="font-normal block truncate">tippe, um zu suchen...</span> <span class="font-normal block truncate">tippe, um zu suchen...</span>
</li> </li>
</ComboboxOption> </ComboboxOption>
<ComboboxOption v-else-if="filtered.length === 0" as="template" disabled> <ComboboxOption v-else-if="available.length === 0 && query != ''" as="template" disabled>
<li class="text-text relative cursor-default select-none py-2 pl-3 pr-4"> <li class="text-text relative cursor-default select-none py-2 pl-3 pr-4">
<span class="font-normal block truncate">Keine Auswahl gefunden.</span> <span class="font-normal block truncate">Keine Auswahl gefunden.</span>
</li> </li>
@ -39,7 +39,7 @@
<ComboboxOption <ComboboxOption
v-if="!(loading || deferingSearch)" v-if="!(loading || deferingSearch)"
v-for="inspectionPlan in filtered" v-for="inspectionPlan in available"
as="template" as="template"
:key="inspectionPlan.id" :key="inspectionPlan.id"
:value="inspectionPlan.id" :value="inspectionPlan.id"
@ -129,11 +129,15 @@ export default defineComponent({
deferingSearch: false as boolean, deferingSearch: false as boolean,
timer: undefined as any, timer: undefined as any,
query: "" as string, query: "" as string,
all: [] as Array<InspectionPlanViewModel>,
filtered: [] as Array<InspectionPlanViewModel>, filtered: [] as Array<InspectionPlanViewModel>,
chosen: undefined as undefined | InspectionPlanViewModel, chosen: undefined as undefined | InspectionPlanViewModel,
}; };
}, },
computed: { computed: {
available() {
return this.query == "" ? this.all : this.filtered;
},
selected: { selected: {
get() { get() {
return this.modelValue; return this.modelValue;
@ -146,9 +150,25 @@ export default defineComponent({
}, },
mounted() { mounted() {
this.loadInspectionPlanInitial(); this.loadInspectionPlanInitial();
this.preloadAll();
}, },
methods: { methods: {
...mapActions(useInspectionPlanStore, ["searchInspectionPlans", "fetchInspectionPlanById"]), ...mapActions(useInspectionPlanStore, [
"searchInspectionPlans",
"fetchInspectionPlanById",
"getAllInspectionPlans",
]),
preloadAll() {
this.loading = true;
this.getAllInspectionPlans()
.then((res) => {
this.all = res.data;
})
.catch((err) => {})
.finally(() => {
this.loading = false;
});
},
search() { search() {
this.filtered = []; this.filtered = [];
if (this.query == "") return; if (this.query == "") return;

View file

@ -32,12 +32,12 @@
<span class="font-normal block truncate">suche</span> <span class="font-normal block truncate">suche</span>
</li> </li>
</ComboboxOption> </ComboboxOption>
<ComboboxOption v-else-if="filtered.length === 0 && query == ''" as="template" disabled> <ComboboxOption v-else-if="available.length === 0" as="template" disabled>
<li class="text-text relative cursor-default select-none py-2 pl-3 pr-4"> <li class="text-text relative cursor-default select-none py-2 pl-3 pr-4">
<span class="font-normal block truncate">tippe, um zu suchen...</span> <span class="font-normal block truncate">tippe, um zu suchen...</span>
</li> </li>
</ComboboxOption> </ComboboxOption>
<ComboboxOption v-else-if="filtered.length === 0" as="template" disabled> <ComboboxOption v-else-if="available.length === 0 && query != ''" as="template" disabled>
<li class="text-text relative cursor-default select-none py-2 pl-3 pr-4"> <li class="text-text relative cursor-default select-none py-2 pl-3 pr-4">
<span class="font-normal block truncate">Keine Auswahl gefunden.</span> <span class="font-normal block truncate">Keine Auswahl gefunden.</span>
</li> </li>
@ -45,7 +45,7 @@
<ComboboxOption <ComboboxOption
v-if="!(loading || deferingSearch)" v-if="!(loading || deferingSearch)"
v-for="vehicle in filtered" v-for="vehicle in available"
as="template" as="template"
:key="vehicle.id" :key="vehicle.id"
:value="vehicle.id" :value="vehicle.id"
@ -137,11 +137,15 @@ export default defineComponent({
deferingSearch: false as boolean, deferingSearch: false as boolean,
timer: undefined as any, timer: undefined as any,
query: "" as string, query: "" as string,
all: [] as Array<VehicleViewModel>,
filtered: [] as Array<VehicleViewModel>, filtered: [] as Array<VehicleViewModel>,
chosen: undefined as undefined | VehicleViewModel, chosen: undefined as undefined | VehicleViewModel,
}; };
}, },
computed: { computed: {
available() {
return this.query == "" ? this.all : this.filtered;
},
selected: { selected: {
get() { get() {
return this.modelValue; return this.modelValue;
@ -154,10 +158,22 @@ export default defineComponent({
}, },
mounted() { mounted() {
this.loadVehicleInitial(); this.loadVehicleInitial();
this.preloadAll();
}, },
methods: { methods: {
...mapActions(useVehicleStore, ["searchVehicles", "fetchVehicleById"]), ...mapActions(useVehicleStore, ["searchVehicles", "fetchVehicleById", "getAllVehicles"]),
...mapActions(useModalStore, ["openModal"]), ...mapActions(useModalStore, ["openModal"]),
preloadAll() {
this.loading = true;
this.getAllVehicles()
.then((res) => {
this.all = res.data;
})
.catch((err) => {})
.finally(() => {
this.loading = false;
});
},
search() { search() {
this.filtered = []; this.filtered = [];
if (this.query == "") return; if (this.query == "") return;

View file

@ -26,12 +26,12 @@
<span class="font-normal block truncate">suche</span> <span class="font-normal block truncate">suche</span>
</li> </li>
</ComboboxOption> </ComboboxOption>
<ComboboxOption v-else-if="filtered.length === 0 && query == ''" as="template" disabled> <ComboboxOption v-else-if="available.length === 0" as="template" disabled>
<li class="text-text relative cursor-default select-none py-2 pl-3 pr-4"> <li class="text-text relative cursor-default select-none py-2 pl-3 pr-4">
<span class="font-normal block truncate">tippe, um zu suchen...</span> <span class="font-normal block truncate">tippe, um zu suchen...</span>
</li> </li>
</ComboboxOption> </ComboboxOption>
<ComboboxOption v-else-if="filtered.length === 0" as="template" disabled> <ComboboxOption v-else-if="available.length === 0 && query != ''" as="template" disabled>
<li class="text-text relative cursor-default select-none py-2 pl-3 pr-4"> <li class="text-text relative cursor-default select-none py-2 pl-3 pr-4">
<span class="font-normal block truncate">Keine Auswahl gefunden.</span> <span class="font-normal block truncate">Keine Auswahl gefunden.</span>
</li> </li>
@ -39,7 +39,7 @@
<ComboboxOption <ComboboxOption
v-if="!(loading || deferingSearch)" v-if="!(loading || deferingSearch)"
v-for="vehicleType in filtered" v-for="vehicleType in available"
as="template" as="template"
:key="vehicleType.id" :key="vehicleType.id"
:value="vehicleType.id" :value="vehicleType.id"
@ -125,11 +125,15 @@ export default defineComponent({
deferingSearch: false as boolean, deferingSearch: false as boolean,
timer: undefined as any, timer: undefined as any,
query: "" as string, query: "" as string,
all: [] as Array<VehicleTypeViewModel>,
filtered: [] as Array<VehicleTypeViewModel>, filtered: [] as Array<VehicleTypeViewModel>,
chosen: undefined as undefined | VehicleTypeViewModel, chosen: undefined as undefined | VehicleTypeViewModel,
}; };
}, },
computed: { computed: {
available() {
return this.query == "" ? this.all : this.filtered;
},
selected: { selected: {
get() { get() {
return this.modelValue; return this.modelValue;
@ -142,9 +146,21 @@ export default defineComponent({
}, },
mounted() { mounted() {
this.loadVehicleTypeInitial(); this.loadVehicleTypeInitial();
this.preloadAll();
}, },
methods: { methods: {
...mapActions(useVehicleTypeStore, ["searchVehicleTypes", "fetchVehicleTypeById"]), ...mapActions(useVehicleTypeStore, ["searchVehicleTypes", "fetchVehicleTypeById", "getAllVehicleTypes"]),
preloadAll() {
this.loading = true;
this.getAllVehicleTypes()
.then((res) => {
this.all = res.data;
})
.catch((err) => {})
.finally(() => {
this.loading = false;
});
},
search() { search() {
this.filtered = []; this.filtered = [];
if (this.query == "") return; if (this.query == "") return;

View file

@ -32,12 +32,12 @@
<span class="font-normal block truncate">suche</span> <span class="font-normal block truncate">suche</span>
</li> </li>
</ComboboxOption> </ComboboxOption>
<ComboboxOption v-else-if="filtered.length === 0 && query == ''" as="template" disabled> <ComboboxOption v-else-if="available.length === 0 && all.length == 0" as="template" disabled>
<li class="text-text relative cursor-default select-none py-2 pl-3 pr-4"> <li class="text-text relative cursor-default select-none py-2 pl-3 pr-4">
<span class="font-normal block truncate">tippe, um zu suchen...</span> <span class="font-normal block truncate">tippe, um zu suchen...</span>
</li> </li>
</ComboboxOption> </ComboboxOption>
<ComboboxOption v-else-if="filtered.length === 0" as="template" disabled> <ComboboxOption v-else-if="available.length === 0 && query != ''" as="template" disabled>
<li class="text-text relative cursor-default select-none py-2 pl-3 pr-4"> <li class="text-text relative cursor-default select-none py-2 pl-3 pr-4">
<span class="font-normal block truncate">Keine Auswahl gefunden.</span> <span class="font-normal block truncate">Keine Auswahl gefunden.</span>
</li> </li>
@ -45,7 +45,7 @@
<ComboboxOption <ComboboxOption
v-if="!(loading || deferingSearch)" v-if="!(loading || deferingSearch)"
v-for="wearable in filtered" v-for="wearable in available"
as="template" as="template"
:key="wearable.id" :key="wearable.id"
:value="wearable.id" :value="wearable.id"
@ -137,11 +137,15 @@ export default defineComponent({
deferingSearch: false as boolean, deferingSearch: false as boolean,
timer: undefined as any, timer: undefined as any,
query: "" as string, query: "" as string,
all: [] as Array<WearableViewModel>,
filtered: [] as Array<WearableViewModel>, filtered: [] as Array<WearableViewModel>,
chosen: undefined as undefined | WearableViewModel, chosen: undefined as undefined | WearableViewModel,
}; };
}, },
computed: { computed: {
available() {
return this.query == "" ? this.all : this.filtered;
},
selected: { selected: {
get() { get() {
return this.modelValue; return this.modelValue;
@ -154,10 +158,22 @@ export default defineComponent({
}, },
mounted() { mounted() {
this.loadWearableInitial(); this.loadWearableInitial();
this.preloadAll();
}, },
methods: { methods: {
...mapActions(useWearableStore, ["searchWearables", "fetchWearableById"]), ...mapActions(useWearableStore, ["searchWearables", "fetchWearableById", "getAllWearables"]),
...mapActions(useModalStore, ["openModal"]), ...mapActions(useModalStore, ["openModal"]),
preloadAll() {
this.loading = true;
this.getAllWearables()
.then((res) => {
this.all = res.data;
})
.catch((err) => {})
.finally(() => {
this.loading = false;
});
},
search() { search() {
this.filtered = []; this.filtered = [];
if (this.query == "") return; if (this.query == "") return;
@ -172,7 +188,7 @@ export default defineComponent({
}); });
}, },
getWearableFromSearch(id: string) { getWearableFromSearch(id: string) {
return this.filtered.find((f) => f.id == id); return this.all.find((f) => f.id == id);
}, },
loadWearableInitial() { loadWearableInitial() {
if (this.modelValue == "") return; if (this.modelValue == "") return;

View file

@ -26,12 +26,12 @@
<span class="font-normal block truncate">suche</span> <span class="font-normal block truncate">suche</span>
</li> </li>
</ComboboxOption> </ComboboxOption>
<ComboboxOption v-else-if="filtered.length === 0 && query == ''" as="template" disabled> <ComboboxOption v-else-if="available.length === 0 && all.length == 0" as="template" disabled>
<li class="text-text relative cursor-default select-none py-2 pl-3 pr-4"> <li class="text-text relative cursor-default select-none py-2 pl-3 pr-4">
<span class="font-normal block truncate">tippe, um zu suchen...</span> <span class="font-normal block truncate">tippe, um zu suchen...</span>
</li> </li>
</ComboboxOption> </ComboboxOption>
<ComboboxOption v-else-if="filtered.length === 0" as="template" disabled> <ComboboxOption v-else-if="available.length === 0 && query != ''" as="template" disabled>
<li class="text-text relative cursor-default select-none py-2 pl-3 pr-4"> <li class="text-text relative cursor-default select-none py-2 pl-3 pr-4">
<span class="font-normal block truncate">Keine Auswahl gefunden.</span> <span class="font-normal block truncate">Keine Auswahl gefunden.</span>
</li> </li>
@ -39,7 +39,7 @@
<ComboboxOption <ComboboxOption
v-if="!(loading || deferingSearch)" v-if="!(loading || deferingSearch)"
v-for="wearableType in filtered" v-for="wearableType in available"
as="template" as="template"
:key="wearableType.id" :key="wearableType.id"
:value="wearableType.id" :value="wearableType.id"
@ -125,11 +125,15 @@ export default defineComponent({
deferingSearch: false as boolean, deferingSearch: false as boolean,
timer: undefined as any, timer: undefined as any,
query: "" as string, query: "" as string,
all: [] as Array<WearableTypeViewModel>,
filtered: [] as Array<WearableTypeViewModel>, filtered: [] as Array<WearableTypeViewModel>,
chosen: undefined as undefined | WearableTypeViewModel, chosen: undefined as undefined | WearableTypeViewModel,
}; };
}, },
computed: { computed: {
available() {
return this.query == "" ? this.all : this.filtered;
},
selected: { selected: {
get() { get() {
return this.modelValue; return this.modelValue;
@ -142,9 +146,21 @@ export default defineComponent({
}, },
mounted() { mounted() {
this.loadWearableTypeInitial(); this.loadWearableTypeInitial();
this.preloadAll();
}, },
methods: { methods: {
...mapActions(useWearableTypeStore, ["searchWearableTypes", "fetchWearableTypeById"]), ...mapActions(useWearableTypeStore, ["searchWearableTypes", "fetchWearableTypeById", "getAllWearableTypes"]),
preloadAll() {
this.loading = true;
this.getAllWearableTypes()
.then((res) => {
this.all = res.data;
})
.catch((err) => {})
.finally(() => {
this.loading = false;
});
},
search() { search() {
this.filtered = []; this.filtered = [];
if (this.query == "") return; if (this.query == "") return;
@ -159,7 +175,7 @@ export default defineComponent({
}); });
}, },
getWearableTypeFromSearch(id: string) { getWearableTypeFromSearch(id: string) {
return this.filtered.find((f) => f.id == id); return this.all.find((f) => f.id == id);
}, },
loadWearableTypeInitial() { loadWearableTypeInitial() {
if (this.modelValue == "") return; if (this.modelValue == "") return;