mirror of
https://github.com/mealie-recipes/mealie.git
synced 2025-07-19 13:19:41 +02:00
fix: Refactor Stores and Fix Missing Public Cookbooks (#5611)
Co-authored-by: Kuchenpirat <24235032+Kuchenpirat@users.noreply.github.com>
This commit is contained in:
parent
2f19d31d1b
commit
aad7dc1abd
11 changed files with 96 additions and 45 deletions
|
@ -138,14 +138,48 @@ export default defineNuxtComponent({
|
||||||
const groupSlug = computed(() => route.params.groupSlug as string || $auth.user.value?.groupSlug || "");
|
const groupSlug = computed(() => route.params.groupSlug as string || $auth.user.value?.groupSlug || "");
|
||||||
|
|
||||||
const cookbookPreferences = useCookbookPreferences();
|
const cookbookPreferences = useCookbookPreferences();
|
||||||
const { store: cookbooks, actions: cookbooksActions } = isOwnGroup.value ? useCookbookStore() : usePublicCookbookStore(groupSlug.value || "");
|
|
||||||
onMounted(() => {
|
const ownCookbookStore = useCookbookStore(i18n);
|
||||||
if (!cookbooks.value.length) {
|
const ownHouseholdStore = useHouseholdStore(i18n);
|
||||||
cookbooksActions.refresh();
|
|
||||||
|
const publicCookbookStoreCache = ref<Record<string, ReturnType<typeof usePublicCookbookStore>>>({});
|
||||||
|
const publicHouseholdStoreCache = ref<Record<string, ReturnType<typeof usePublicHouseholdStore>>>({});
|
||||||
|
|
||||||
|
function getPublicCookbookStore(slug: string) {
|
||||||
|
if (!publicCookbookStoreCache.value[slug]) {
|
||||||
|
publicCookbookStoreCache.value[slug] = usePublicCookbookStore(slug, i18n);
|
||||||
}
|
}
|
||||||
|
return publicCookbookStoreCache.value[slug];
|
||||||
|
}
|
||||||
|
|
||||||
|
function getPublicHouseholdStore(slug: string) {
|
||||||
|
if (!publicHouseholdStoreCache.value[slug]) {
|
||||||
|
publicHouseholdStoreCache.value[slug] = usePublicHouseholdStore(slug, i18n);
|
||||||
|
}
|
||||||
|
return publicHouseholdStoreCache.value[slug];
|
||||||
|
}
|
||||||
|
|
||||||
|
const cookbooks = computed(() => {
|
||||||
|
if (isOwnGroup.value) {
|
||||||
|
return ownCookbookStore.store.value;
|
||||||
|
}
|
||||||
|
else if (groupSlug.value) {
|
||||||
|
const publicStore = getPublicCookbookStore(groupSlug.value);
|
||||||
|
return unref(publicStore.store);
|
||||||
|
}
|
||||||
|
return [];
|
||||||
});
|
});
|
||||||
|
|
||||||
const { store: households } = isOwnGroup.value ? useHouseholdStore() : usePublicHouseholdStore(groupSlug.value || "");
|
const households = computed(() => {
|
||||||
|
if (isOwnGroup.value) {
|
||||||
|
return ownHouseholdStore.store.value;
|
||||||
|
}
|
||||||
|
else if (groupSlug.value) {
|
||||||
|
const publicStore = getPublicHouseholdStore(groupSlug.value);
|
||||||
|
return unref(publicStore.store);
|
||||||
|
}
|
||||||
|
return [];
|
||||||
|
});
|
||||||
|
|
||||||
const householdsById = computed(() => {
|
const householdsById = computed(() => {
|
||||||
return households.value.reduce((acc, household) => {
|
return households.value.reduce((acc, household) => {
|
||||||
|
@ -178,6 +212,10 @@ export default defineNuxtComponent({
|
||||||
|
|
||||||
const currentUserHouseholdId = computed(() => $auth.user.value?.householdId);
|
const currentUserHouseholdId = computed(() => $auth.user.value?.householdId);
|
||||||
const cookbookLinks = computed<SideBarLink[]>(() => {
|
const cookbookLinks = computed<SideBarLink[]>(() => {
|
||||||
|
if (!cookbooks.value?.length) {
|
||||||
|
return [];
|
||||||
|
}
|
||||||
|
|
||||||
const sortedCookbooks = [...cookbooks.value].sort((a, b) => (a.position || 0) - (b.position || 0));
|
const sortedCookbooks = [...cookbooks.value].sort((a, b) => (a.position || 0) - (b.position || 0));
|
||||||
|
|
||||||
const ownLinks: SideBarLink[] = [];
|
const ownLinks: SideBarLink[] = [];
|
||||||
|
|
|
@ -1,4 +1,5 @@
|
||||||
import type { AxiosInstance, AxiosResponse, AxiosRequestConfig } from "axios";
|
import type { AxiosInstance, AxiosResponse, AxiosRequestConfig } from "axios";
|
||||||
|
import type { Composer } from "vue-i18n";
|
||||||
import type { ApiRequestInstance, RequestResponse } from "~/lib/api/types/non-generated";
|
import type { ApiRequestInstance, RequestResponse } from "~/lib/api/types/non-generated";
|
||||||
import { AdminAPI, PublicApi, UserApi } from "~/lib/api";
|
import { AdminAPI, PublicApi, UserApi } from "~/lib/api";
|
||||||
import { PublicExploreApi } from "~/lib/api/client-public";
|
import { PublicExploreApi } from "~/lib/api/client-public";
|
||||||
|
@ -52,31 +53,34 @@ function getRequests(axiosInstance: AxiosInstance): ApiRequestInstance {
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
export const useRequests = function (): ApiRequestInstance {
|
export const useRequests = function (i18n?: Composer): ApiRequestInstance {
|
||||||
const i18n = useI18n();
|
|
||||||
const { $axios } = useNuxtApp();
|
const { $axios } = useNuxtApp();
|
||||||
|
if (!i18n) {
|
||||||
|
// Only works in a setup block
|
||||||
|
i18n = useI18n();
|
||||||
|
}
|
||||||
|
|
||||||
$axios.defaults.headers.common["Accept-Language"] = i18n.locale.value;
|
$axios.defaults.headers.common["Accept-Language"] = i18n.locale.value;
|
||||||
|
|
||||||
return getRequests($axios);
|
return getRequests($axios);
|
||||||
};
|
};
|
||||||
|
|
||||||
export const useAdminApi = function (): AdminAPI {
|
export const useAdminApi = function (i18n?: Composer): AdminAPI {
|
||||||
const requests = useRequests();
|
const requests = useRequests(i18n);
|
||||||
return new AdminAPI(requests);
|
return new AdminAPI(requests);
|
||||||
};
|
};
|
||||||
|
|
||||||
export const useUserApi = function (): UserApi {
|
export const useUserApi = function (i18n?: Composer): UserApi {
|
||||||
const requests = useRequests();
|
const requests = useRequests(i18n);
|
||||||
return new UserApi(requests);
|
return new UserApi(requests);
|
||||||
};
|
};
|
||||||
|
|
||||||
export const usePublicApi = function (): PublicApi {
|
export const usePublicApi = function (i18n?: Composer): PublicApi {
|
||||||
const requests = useRequests();
|
const requests = useRequests(i18n);
|
||||||
return new PublicApi(requests);
|
return new PublicApi(requests);
|
||||||
};
|
};
|
||||||
|
|
||||||
export const usePublicExploreApi = function (groupSlug: string): PublicExploreApi {
|
export const usePublicExploreApi = function (groupSlug: string, i18n?: Composer): PublicExploreApi {
|
||||||
const requests = useRequests();
|
const requests = useRequests(i18n);
|
||||||
return new PublicExploreApi(requests, groupSlug);
|
return new PublicExploreApi(requests, groupSlug);
|
||||||
};
|
};
|
||||||
|
|
|
@ -1,3 +1,4 @@
|
||||||
|
import type { Composer } from "vue-i18n";
|
||||||
import { useData, useReadOnlyStore, useStore } from "../partials/use-store-factory";
|
import { useData, useReadOnlyStore, useStore } from "../partials/use-store-factory";
|
||||||
import type { RecipeCategory } from "~/lib/api/types/recipe";
|
import type { RecipeCategory } from "~/lib/api/types/recipe";
|
||||||
import { usePublicExploreApi, useUserApi } from "~/composables/api";
|
import { usePublicExploreApi, useUserApi } from "~/composables/api";
|
||||||
|
@ -14,12 +15,12 @@ export const useCategoryData = function () {
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
export const useCategoryStore = function () {
|
export const useCategoryStore = function (i18n?: Composer) {
|
||||||
const api = useUserApi();
|
const api = useUserApi(i18n);
|
||||||
return useStore<RecipeCategory>(store, loading, api.categories);
|
return useStore<RecipeCategory>(store, loading, api.categories);
|
||||||
};
|
};
|
||||||
|
|
||||||
export const usePublicCategoryStore = function (groupSlug: string) {
|
export const usePublicCategoryStore = function (groupSlug: string, i18n?: Composer) {
|
||||||
const api = usePublicExploreApi(groupSlug).explore;
|
const api = usePublicExploreApi(groupSlug, i18n).explore;
|
||||||
return useReadOnlyStore<RecipeCategory>(store, publicLoading, api.categories);
|
return useReadOnlyStore<RecipeCategory>(store, publicLoading, api.categories);
|
||||||
};
|
};
|
||||||
|
|
|
@ -1,3 +1,4 @@
|
||||||
|
import type { Composer } from "vue-i18n";
|
||||||
import { useReadOnlyStore, useStore } from "../partials/use-store-factory";
|
import { useReadOnlyStore, useStore } from "../partials/use-store-factory";
|
||||||
import type { RecipeCookBook } from "~/lib/api/types/cookbook";
|
import type { RecipeCookBook } from "~/lib/api/types/cookbook";
|
||||||
import { usePublicExploreApi, useUserApi } from "~/composables/api";
|
import { usePublicExploreApi, useUserApi } from "~/composables/api";
|
||||||
|
@ -6,12 +7,12 @@ const store: Ref<RecipeCookBook[]> = ref([]);
|
||||||
const loading = ref(false);
|
const loading = ref(false);
|
||||||
const publicLoading = ref(false);
|
const publicLoading = ref(false);
|
||||||
|
|
||||||
export const useCookbookStore = function () {
|
export const useCookbookStore = function (i18n?: Composer) {
|
||||||
const api = useUserApi();
|
const api = useUserApi(i18n);
|
||||||
return useStore<RecipeCookBook>(store, loading, api.cookbooks);
|
return useStore<RecipeCookBook>(store, loading, api.cookbooks);
|
||||||
};
|
};
|
||||||
|
|
||||||
export const usePublicCookbookStore = function (groupSlug: string) {
|
export const usePublicCookbookStore = function (groupSlug: string, i18n?: Composer) {
|
||||||
const api = usePublicExploreApi(groupSlug).explore;
|
const api = usePublicExploreApi(groupSlug, i18n).explore;
|
||||||
return useReadOnlyStore<RecipeCookBook>(store, publicLoading, api.cookbooks);
|
return useReadOnlyStore<RecipeCookBook>(store, publicLoading, api.cookbooks);
|
||||||
};
|
};
|
||||||
|
|
|
@ -1,3 +1,4 @@
|
||||||
|
import type { Composer } from "vue-i18n";
|
||||||
import { useData, useReadOnlyStore, useStore } from "../partials/use-store-factory";
|
import { useData, useReadOnlyStore, useStore } from "../partials/use-store-factory";
|
||||||
import type { IngredientFood } from "~/lib/api/types/recipe";
|
import type { IngredientFood } from "~/lib/api/types/recipe";
|
||||||
import { usePublicExploreApi, useUserApi } from "~/composables/api";
|
import { usePublicExploreApi, useUserApi } from "~/composables/api";
|
||||||
|
@ -15,12 +16,12 @@ export const useFoodData = function () {
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
export const useFoodStore = function () {
|
export const useFoodStore = function (i18n?: Composer) {
|
||||||
const api = useUserApi();
|
const api = useUserApi(i18n);
|
||||||
return useStore<IngredientFood>(store, loading, api.foods);
|
return useStore<IngredientFood>(store, loading, api.foods);
|
||||||
};
|
};
|
||||||
|
|
||||||
export const usePublicFoodStore = function (groupSlug: string) {
|
export const usePublicFoodStore = function (groupSlug: string, i18n?: Composer) {
|
||||||
const api = usePublicExploreApi(groupSlug).explore;
|
const api = usePublicExploreApi(groupSlug, i18n).explore;
|
||||||
return useReadOnlyStore<IngredientFood>(store, publicLoading, api.foods);
|
return useReadOnlyStore<IngredientFood>(store, publicLoading, api.foods);
|
||||||
};
|
};
|
||||||
|
|
|
@ -1,3 +1,4 @@
|
||||||
|
import type { Composer } from "vue-i18n";
|
||||||
import { useReadOnlyStore } from "../partials/use-store-factory";
|
import { useReadOnlyStore } from "../partials/use-store-factory";
|
||||||
import type { HouseholdSummary } from "~/lib/api/types/household";
|
import type { HouseholdSummary } from "~/lib/api/types/household";
|
||||||
import { usePublicExploreApi, useUserApi } from "~/composables/api";
|
import { usePublicExploreApi, useUserApi } from "~/composables/api";
|
||||||
|
@ -6,12 +7,12 @@ const store: Ref<HouseholdSummary[]> = ref([]);
|
||||||
const loading = ref(false);
|
const loading = ref(false);
|
||||||
const publicLoading = ref(false);
|
const publicLoading = ref(false);
|
||||||
|
|
||||||
export const useHouseholdStore = function () {
|
export const useHouseholdStore = function (i18n?: Composer) {
|
||||||
const api = useUserApi();
|
const api = useUserApi(i18n);
|
||||||
return useReadOnlyStore<HouseholdSummary>(store, loading, api.households);
|
return useReadOnlyStore<HouseholdSummary>(store, loading, api.households);
|
||||||
};
|
};
|
||||||
|
|
||||||
export const usePublicHouseholdStore = function (groupSlug: string) {
|
export const usePublicHouseholdStore = function (groupSlug: string, i18n?: Composer) {
|
||||||
const api = usePublicExploreApi(groupSlug).explore;
|
const api = usePublicExploreApi(groupSlug, i18n).explore;
|
||||||
return useReadOnlyStore<HouseholdSummary>(store, publicLoading, api.households);
|
return useReadOnlyStore<HouseholdSummary>(store, publicLoading, api.households);
|
||||||
};
|
};
|
||||||
|
|
|
@ -1,3 +1,4 @@
|
||||||
|
import type { Composer } from "vue-i18n";
|
||||||
import { useData, useStore } from "../partials/use-store-factory";
|
import { useData, useStore } from "../partials/use-store-factory";
|
||||||
import type { MultiPurposeLabelOut } from "~/lib/api/types/labels";
|
import type { MultiPurposeLabelOut } from "~/lib/api/types/labels";
|
||||||
import { useUserApi } from "~/composables/api";
|
import { useUserApi } from "~/composables/api";
|
||||||
|
@ -14,7 +15,7 @@ export const useLabelData = function () {
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
export const useLabelStore = function () {
|
export const useLabelStore = function (i18n?: Composer) {
|
||||||
const api = useUserApi();
|
const api = useUserApi(i18n);
|
||||||
return useStore<MultiPurposeLabelOut>(store, loading, api.multiPurposeLabels);
|
return useStore<MultiPurposeLabelOut>(store, loading, api.multiPurposeLabels);
|
||||||
};
|
};
|
||||||
|
|
|
@ -1,3 +1,4 @@
|
||||||
|
import type { Composer } from "vue-i18n";
|
||||||
import { useData, useReadOnlyStore, useStore } from "../partials/use-store-factory";
|
import { useData, useReadOnlyStore, useStore } from "../partials/use-store-factory";
|
||||||
import type { RecipeTag } from "~/lib/api/types/recipe";
|
import type { RecipeTag } from "~/lib/api/types/recipe";
|
||||||
import { usePublicExploreApi, useUserApi } from "~/composables/api";
|
import { usePublicExploreApi, useUserApi } from "~/composables/api";
|
||||||
|
@ -14,12 +15,12 @@ export const useTagData = function () {
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
export const useTagStore = function () {
|
export const useTagStore = function (i18n?: Composer) {
|
||||||
const api = useUserApi();
|
const api = useUserApi(i18n);
|
||||||
return useStore<RecipeTag>(store, loading, api.tags);
|
return useStore<RecipeTag>(store, loading, api.tags);
|
||||||
};
|
};
|
||||||
|
|
||||||
export const usePublicTagStore = function (groupSlug: string) {
|
export const usePublicTagStore = function (groupSlug: string, i18n?: Composer) {
|
||||||
const api = usePublicExploreApi(groupSlug).explore;
|
const api = usePublicExploreApi(groupSlug, i18n).explore;
|
||||||
return useReadOnlyStore<RecipeTag>(store, publicLoading, api.tags);
|
return useReadOnlyStore<RecipeTag>(store, publicLoading, api.tags);
|
||||||
};
|
};
|
||||||
|
|
|
@ -1,3 +1,4 @@
|
||||||
|
import type { Composer } from "vue-i18n";
|
||||||
import { useData, useReadOnlyStore, useStore } from "../partials/use-store-factory";
|
import { useData, useReadOnlyStore, useStore } from "../partials/use-store-factory";
|
||||||
import type { RecipeTool } from "~/lib/api/types/recipe";
|
import type { RecipeTool } from "~/lib/api/types/recipe";
|
||||||
import { usePublicExploreApi, useUserApi } from "~/composables/api";
|
import { usePublicExploreApi, useUserApi } from "~/composables/api";
|
||||||
|
@ -20,12 +21,12 @@ export const useToolData = function () {
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
export const useToolStore = function () {
|
export const useToolStore = function (i18n?: Composer) {
|
||||||
const api = useUserApi();
|
const api = useUserApi(i18n);
|
||||||
return useStore<RecipeTool>(store, loading, api.tools);
|
return useStore<RecipeTool>(store, loading, api.tools);
|
||||||
};
|
};
|
||||||
|
|
||||||
export const usePublicToolStore = function (groupSlug: string) {
|
export const usePublicToolStore = function (groupSlug: string, i18n?: Composer) {
|
||||||
const api = usePublicExploreApi(groupSlug).explore;
|
const api = usePublicExploreApi(groupSlug, i18n).explore;
|
||||||
return useReadOnlyStore<RecipeTool>(store, publicLoading, api.tools);
|
return useReadOnlyStore<RecipeTool>(store, publicLoading, api.tools);
|
||||||
};
|
};
|
||||||
|
|
|
@ -1,3 +1,4 @@
|
||||||
|
import type { Composer } from "vue-i18n";
|
||||||
import { useData, useStore } from "../partials/use-store-factory";
|
import { useData, useStore } from "../partials/use-store-factory";
|
||||||
import type { IngredientUnit } from "~/lib/api/types/recipe";
|
import type { IngredientUnit } from "~/lib/api/types/recipe";
|
||||||
import { useUserApi } from "~/composables/api";
|
import { useUserApi } from "~/composables/api";
|
||||||
|
@ -15,7 +16,7 @@ export const useUnitData = function () {
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
export const useUnitStore = function () {
|
export const useUnitStore = function (i18n?: Composer) {
|
||||||
const api = useUserApi();
|
const api = useUserApi(i18n);
|
||||||
return useStore<IngredientUnit>(store, loading, api.units);
|
return useStore<IngredientUnit>(store, loading, api.units);
|
||||||
};
|
};
|
||||||
|
|
|
@ -1,3 +1,4 @@
|
||||||
|
import type { Composer } from "vue-i18n";
|
||||||
import { useReadOnlyStore } from "../partials/use-store-factory";
|
import { useReadOnlyStore } from "../partials/use-store-factory";
|
||||||
import { useRequests } from "../api/api-client";
|
import { useRequests } from "../api/api-client";
|
||||||
import type { UserSummary } from "~/lib/api/types/user";
|
import type { UserSummary } from "~/lib/api/types/user";
|
||||||
|
@ -11,8 +12,8 @@ class GroupUserAPIReadOnly extends BaseCRUDAPIReadOnly<UserSummary> {
|
||||||
itemRoute = (idOrUsername: string | number) => `/groups/members/${idOrUsername}`;
|
itemRoute = (idOrUsername: string | number) => `/groups/members/${idOrUsername}`;
|
||||||
}
|
}
|
||||||
|
|
||||||
export const useUserStore = function () {
|
export const useUserStore = function (i18n?: Composer) {
|
||||||
const requests = useRequests();
|
const requests = useRequests(i18n);
|
||||||
const api = new GroupUserAPIReadOnly(requests);
|
const api = new GroupUserAPIReadOnly(requests);
|
||||||
|
|
||||||
return useReadOnlyStore<UserSummary>(store, loading, api, { orderBy: "full_name" });
|
return useReadOnlyStore<UserSummary>(store, loading, api, { orderBy: "full_name" });
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue