Organizers Page

This commit is contained in:
Kuchenpirat 2025-07-30 12:18:05 +00:00
commit 48d836beeb

View file

@ -122,9 +122,8 @@
</div> </div>
</template> </template>
<script lang="ts"> <script setup lang="ts">
import Fuse from "fuse.js"; import Fuse from "fuse.js";
import { useContextPresets } from "~/composables/use-context-presents"; import { useContextPresets } from "~/composables/use-context-presents";
import RecipeOrganizerDialog from "~/components/Domain/Recipe/RecipeOrganizerDialog.vue"; import RecipeOrganizerDialog from "~/components/Domain/Recipe/RecipeOrganizerDialog.vue";
import { Organizer, type RecipeOrganizer } from "~/lib/api/types/non-generated"; import { Organizer, type RecipeOrganizer } from "~/lib/api/types/non-generated";
@ -138,27 +137,18 @@ interface GenericItem {
onHand: boolean; onHand: boolean;
} }
export default defineNuxtComponent({ const props = defineProps<{
components: { items: GenericItem[];
RecipeOrganizerDialog, icon: string;
}, itemType: RecipeOrganizer;
props: { }>();
items: {
type: Array as () => GenericItem[], const emit = defineEmits<{
required: true, update: [item: GenericItem];
}, delete: [id: string];
icon: { }>();
type: String,
required: true, const state = reactive({
},
itemType: {
type: String as () => RecipeOrganizer,
required: true,
},
},
emits: ["update", "delete"],
setup(props, { emit }) {
const state = reactive({
// Search Options // Search Options
options: { options: {
ignoreLocation: true, ignoreLocation: true,
@ -171,24 +161,24 @@ export default defineNuxtComponent({
minMatchCharLength: 1, minMatchCharLength: 1,
keys: ["name"], keys: ["name"],
}, },
}); });
const $auth = useMealieAuth(); const $auth = useMealieAuth();
const route = useRoute(); const route = useRoute();
const groupSlug = computed(() => route.params.groupSlug as string || $auth.user?.value?.groupSlug || ""); const groupSlug = computed(() => route.params.groupSlug as string || $auth.user?.value?.groupSlug || "");
// ================================================================= // =================================================================
// Context Menu // Context Menu
const dialogs = ref({ const dialogs = ref({
organizer: false, organizer: false,
update: false, update: false,
delete: false, delete: false,
}); });
const presets = useContextPresets(); const presets = useContextPresets();
const translationKey = computed<string>(() => { const translationKey = computed<string>(() => {
const typeMap = { const typeMap = {
categories: "category.category", categories: "category.category",
tags: "tag.tag", tags: "tag.tag",
@ -197,58 +187,58 @@ export default defineNuxtComponent({
households: "household.household", households: "household.household",
}; };
return typeMap[props.itemType] || ""; return typeMap[props.itemType] || "";
}); });
const deleteTarget = ref<GenericItem | null>(null); const deleteTarget = ref<GenericItem | null>(null);
const updateTarget = ref<GenericItem | null>(null); const updateTarget = ref<GenericItem | null>(null);
function confirmDelete(item: GenericItem) { function confirmDelete(item: GenericItem) {
deleteTarget.value = item; deleteTarget.value = item;
dialogs.value.delete = true; dialogs.value.delete = true;
} }
function deleteOne() { function deleteOne() {
if (!deleteTarget.value) { if (!deleteTarget.value) {
return; return;
} }
emit("delete", deleteTarget.value.id); emit("delete", deleteTarget.value.id);
} }
function openUpdateDialog(item: GenericItem) { function openUpdateDialog(item: GenericItem) {
updateTarget.value = deepCopy(item); updateTarget.value = deepCopy(item);
dialogs.value.update = true; dialogs.value.update = true;
} }
function updateOne() { function updateOne() {
if (!updateTarget.value) { if (!updateTarget.value) {
return; return;
} }
emit("update", updateTarget.value); emit("update", updateTarget.value);
} }
// ================================================================ // ================================================================
// Search Functions // Search Functions
const searchString = useRouteQuery("q", ""); const searchString = useRouteQuery("q", "");
const fuse = computed(() => { const fuse = computed(() => {
return new Fuse(props.items, state.options); return new Fuse(props.items, state.options);
}); });
const fuzzyItems = computed<GenericItem[]>(() => { const fuzzyItems = computed<GenericItem[]>(() => {
if (searchString.value.trim() === "") { if (searchString.value.trim() === "") {
return props.items; return props.items;
} }
const result = fuse.value.search(searchString.value.trim() as string); const result = fuse.value.search(searchString.value.trim() as string);
return result.map(x => x.item); return result.map(x => x.item);
}); });
// ================================================================= // =================================================================
// Sorted Items // Sorted Items
const itemsSorted = computed(() => { const itemsSorted = computed(() => {
const byLetter: { [key: string]: Array<GenericItem> } = {}; const byLetter: { [key: string]: Array<GenericItem> } = {};
if (!fuzzyItems.value) { if (!fuzzyItems.value) {
@ -266,28 +256,9 @@ export default defineNuxtComponent({
}); });
return byLetter; return byLetter;
});
function isTitle(str: number | string) {
return typeof str === "string" && str.length === 1;
}
return {
groupSlug,
isTitle,
dialogs,
confirmDelete,
openUpdateDialog,
updateOne,
updateTarget,
deleteOne,
deleteTarget,
Organizer,
presets,
itemsSorted,
searchString,
translationKey,
};
},
}); });
function isTitle(str: number | string) {
return typeof str === "string" && str.length === 1;
}
</script> </script>