fix: Cookbooks not rendering on sidebar (#5570)

This commit is contained in:
Michael Genson 2025-06-24 02:36:40 -05:00 committed by GitHub
parent 181aebf424
commit c965d12bf1
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
5 changed files with 34 additions and 162 deletions

View file

@ -70,7 +70,8 @@
<script lang="ts">
import { useLazyRecipes } from "~/composables/recipes";
import RecipeCardSection from "@/components/Domain/Recipe/RecipeCardSection.vue";
import { useCookbook, useCookbooks } from "~/composables/use-group-cookbooks";
import { useCookbookStore } from "~/composables/store/use-cookbook-store";
import { useCookbook } from "~/composables/use-group-cookbooks";
import { useLoggedInState } from "~/composables/use-logged-in-state";
import type { RecipeCookBook } from "~/lib/api/types/cookbook";
import CookbookEditor from "~/components/Domain/Cookbook/CookbookEditor.vue";
@ -87,7 +88,7 @@ export default defineNuxtComponent({
const { recipes, appendRecipes, assignSorted, removeRecipe, replaceRecipes } = useLazyRecipes(isOwnGroup.value ? null : groupSlug.value);
const slug = route.params.slug as string;
const { getOne } = useCookbook(isOwnGroup.value ? null : groupSlug.value);
const { actions } = useCookbooks();
const { actions } = useCookbookStore();
const router = useRouter();
const tab = ref(null);

View file

@ -119,8 +119,8 @@
import { useLoggedInState } from "~/composables/use-logged-in-state";
import type { SideBarLink } from "~/types/application-types";
import { useAppInfo } from "~/composables/api";
import { useCookbooks, usePublicCookbooks } from "~/composables/use-group-cookbooks";
import { useCookbookPreferences } from "~/composables/use-users/preferences";
import { useCookbookStore, usePublicCookbookStore } from "~/composables/store/use-cookbook-store";
import { useHouseholdStore, usePublicHouseholdStore } from "~/composables/store/use-household-store";
import { useToggleDarkMode } from "~/composables/use-utils";
import type { ReadCookBook } from "~/lib/api/types/cookbook";
@ -136,9 +136,15 @@ export default defineNuxtComponent({
const isAdmin = computed(() => $auth.user.value?.admin);
const route = useRoute();
const groupSlug = computed(() => route.params.groupSlug as string || $auth.user.value?.groupSlug || "");
const { cookbooks } = isOwnGroup.value ? useCookbooks() : usePublicCookbooks(groupSlug.value || "");
const cookbookPreferences = useCookbookPreferences();
const { store: cookbooks, actions: cookbooksActions } = isOwnGroup.value ? useCookbookStore() : usePublicCookbookStore(groupSlug.value || "");
onMounted(() => {
if (!cookbooks.value.length) {
cookbooksActions.refresh();
}
});
const { store: households } = isOwnGroup.value ? useHouseholdStore() : usePublicHouseholdStore(groupSlug.value || "");
const householdsById = computed(() => {
@ -172,10 +178,6 @@ export default defineNuxtComponent({
const currentUserHouseholdId = computed(() => $auth.user.value?.householdId);
const cookbookLinks = computed<SideBarLink[]>(() => {
if (!cookbooks.value || !households.value) {
return [];
}
const sortedCookbooks = [...cookbooks.value].sort((a, b) => (a.position || 0) - (b.position || 0));
const ownLinks: SideBarLink[] = [];

View file

@ -0,0 +1,17 @@
import { useReadOnlyStore, useStore } from "../partials/use-store-factory";
import type { RecipeCookBook } from "~/lib/api/types/cookbook";
import { usePublicExploreApi, useUserApi } from "~/composables/api";
const store: Ref<RecipeCookBook[]> = ref([]);
const loading = ref(false);
const publicLoading = ref(false);
export const useCookbookStore = function () {
const api = useUserApi();
return useStore<RecipeCookBook>(store, loading, api.cookbooks);
};
export const usePublicCookbookStore = function (groupSlug: string) {
const api = usePublicExploreApi(groupSlug).explore;
return useReadOnlyStore<RecipeCookBook>(store, publicLoading, api.cookbooks);
};

View file

@ -1,10 +1,6 @@
import { useAsyncKey } from "./use-utils";
import { usePublicExploreApi } from "./api/api-client";
import { useHouseholdSelf } from "./use-households";
import { useUserApi } from "~/composables/api";
import type { ReadCookBook, UpdateCookBook } from "~/lib/api/types/cookbook";
let cookbookStore: Ref<ReadCookBook[] | null> | null = null;
export const useCookbook = function (publicGroupSlug: string | null = null) {
function getOne(id: string | number) {
@ -22,149 +18,3 @@ export const useCookbook = function (publicGroupSlug: string | null = null) {
return { getOne };
};
export const usePublicCookbooks = function (groupSlug: string) {
const api = usePublicExploreApi(groupSlug).explore;
const loading = ref(false);
const actions = {
getAll() {
loading.value = true;
const { data: units } = useAsyncData(useAsyncKey(), async () => {
const { data } = await api.cookbooks.getAll(1, -1, { orderBy: "position", orderDirection: "asc" });
if (data) {
return data.items;
}
else {
return null;
}
});
loading.value = false;
return units;
},
async refreshAll() {
loading.value = true;
const { data } = await api.cookbooks.getAll(1, -1, { orderBy: "position", orderDirection: "asc" });
if (data && data.items && cookbookStore) {
cookbookStore.value = data.items;
}
loading.value = false;
},
flushStore() {
cookbookStore = null;
},
};
if (!cookbookStore) {
cookbookStore = actions.getAll();
}
return { cookbooks: cookbookStore, actions };
};
export const useCookbooks = function () {
const api = useUserApi();
const { household } = useHouseholdSelf();
const loading = ref(false);
const i18n = useI18n();
const actions = {
getAll() {
loading.value = true;
const { data: units } = useAsyncData(useAsyncKey(), async () => {
const { data } = await api.cookbooks.getAll(1, -1, { orderBy: "position", orderDirection: "asc" });
if (data) {
return data.items;
}
else {
return null;
}
});
loading.value = false;
return units;
},
async refreshAll() {
loading.value = true;
const { data } = await api.cookbooks.getAll(1, -1, { orderBy: "position", orderDirection: "asc" });
if (data && data.items && cookbookStore) {
cookbookStore.value = data.items;
}
loading.value = false;
},
async createOne(name: string | null = null) {
loading.value = true;
const { data } = await api.cookbooks.createOne({
name: name || i18n.t("cookbook.household-cookbook-name", [household.value?.name || "", String((cookbookStore?.value?.length ?? 0) + 1)]) as string,
position: (cookbookStore?.value?.length ?? 0) + 1,
queryFilterString: "",
});
if (data && cookbookStore?.value) {
cookbookStore.value.push(data);
}
else {
this.refreshAll();
}
loading.value = false;
return data;
},
async updateOne(updateData: UpdateCookBook) {
if (!updateData.id) {
return;
}
loading.value = true;
const { data } = await api.cookbooks.updateOne(updateData.id, updateData);
if (data && cookbookStore?.value) {
this.refreshAll();
}
loading.value = false;
return data;
},
async updateOrder(cookbooks: ReadCookBook[]) {
if (!cookbooks?.length) {
return;
}
loading.value = true;
cookbooks.forEach((element, index) => {
element.position = index + 1;
});
const { data } = await api.cookbooks.updateAll(cookbooks);
if (data && cookbookStore?.value) {
this.refreshAll();
}
loading.value = true;
},
async deleteOne(id: string | number) {
loading.value = true;
const { data } = await api.cookbooks.deleteOne(id);
if (data && cookbookStore?.value) {
this.refreshAll();
}
},
flushStore() {
cookbookStore = null;
},
};
if (!cookbookStore) {
cookbookStore = actions.getAll();
}
return { cookbooks: cookbookStore, actions };
};

View file

@ -139,10 +139,10 @@
<script lang="ts">
import { VueDraggable } from "vue-draggable-plus";
import { useCookbooks } from "@/composables/use-group-cookbooks";
import { useCookbookStore } from "~/composables/store/use-cookbook-store";
import { useHouseholdSelf } from "@/composables/use-households";
import CookbookEditor from "~/components/Domain/Cookbook/CookbookEditor.vue";
import type { ReadCookBook } from "~/lib/api/types/cookbook";
import type { CreateCookBook, ReadCookBook } from "~/lib/api/types/cookbook";
import { useCookbookPreferences } from "~/composables/use-users/preferences";
export default defineNuxtComponent({
@ -162,7 +162,7 @@ export default defineNuxtComponent({
});
const $auth = useMealieAuth();
const { cookbooks: allCookbooks, actions } = useCookbooks();
const { store: allCookbooks, actions } = useCookbookStore();
// Make a local reactive copy of myCookbooks
const myCookbooks = ref<ReadCookBook[]>([]);
@ -188,7 +188,9 @@ export default defineNuxtComponent({
household.value?.name || "",
String((myCookbooks.value?.length ?? 0) + 1),
]) as string;
await actions.createOne(name).then((cookbook) => {
const data = { name } as CreateCookBook;
await actions.createOne(data).then((cookbook) => {
if (!cookbook) {
return;
}