Skip to content

Commit

Permalink
Merge branch 'mealie-next' into mealie-next
Browse files Browse the repository at this point in the history
  • Loading branch information
Gulianrdgd authored Nov 6, 2024
2 parents ee07ce6 + 0fed5f5 commit 782cdcf
Show file tree
Hide file tree
Showing 22 changed files with 470 additions and 146 deletions.
2 changes: 1 addition & 1 deletion .pre-commit-config.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ repos:
exclude: ^tests/data/
- repo: https://github.com/astral-sh/ruff-pre-commit
# Ruff version.
rev: v0.7.1
rev: v0.7.2
hooks:
- id: ruff
- id: ruff-format
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,15 @@ Changing the webworker settings may cause unforeseen memory leak issues with Mea
| --------------- | :-----: | ----------------------------------------------------------------------------- |
| UVICORN_WORKERS | 1 | Sets the number of workers for the web server. [More info here][unicorn_workers] |

### TLS

Use this only when mealie is run without a webserver or reverse proxy.

| Variables | Default | Description |
| -------------------- | :-----: | ------------------------ |
| TLS_CERTIFICATE_PATH | None | File path to Certificate |
| TLS_PRIVATE_KEY_PATH | None | File path to private key |

### LDAP

| Variables | Default | Description |
Expand Down
15 changes: 12 additions & 3 deletions frontend/components/Domain/Cookbook/CookbookPage.vue
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
width="100%"
max-width="1100px"
:icon="$globals.icons.pages"
:title="$t('general.edit')"
:title="$tc('general.edit')"
:submit-icon="$globals.icons.save"
:submit-text="$tc('general.save')"
:submit-disabled="!editTarget.queryFilterString"
Expand All @@ -25,7 +25,7 @@
<v-toolbar-title class="headline"> {{ book.name }} </v-toolbar-title>
<v-spacer></v-spacer>
<BaseButton
v-if="isOwnGroup"
v-if="canEdit"
class="mx-1"
:edit="true"
@click="handleEditCookbook"
Expand Down Expand Up @@ -79,6 +79,15 @@
const tab = ref(null);
const book = getOne(slug);
const isOwnHousehold = computed(() => {
if (!($auth.user && book.value?.householdId)) {
return false;
}
return $auth.user.householdId === book.value.householdId;
})
const canEdit = computed(() => isOwnGroup.value && isOwnHousehold.value);
const dialogStates = reactive({
edit: false,
});
Expand Down Expand Up @@ -118,7 +127,7 @@
recipes,
removeRecipe,
replaceRecipes,
isOwnGroup,
canEdit,
dialogStates,
editTarget,
handleEditCookbook,
Expand Down
88 changes: 65 additions & 23 deletions frontend/components/Layout/DefaultLayout.vue
Original file line number Diff line number Diff line change
Expand Up @@ -82,12 +82,17 @@ import { computed, defineComponent, onMounted, ref, useContext, useRoute } from
import { useLoggedInState } from "~/composables/use-logged-in-state";
import AppHeader from "@/components/Layout/LayoutParts/AppHeader.vue";
import AppSidebar from "@/components/Layout/LayoutParts/AppSidebar.vue";
import { SidebarLinks } from "~/types/application-types";
import { SideBarLink } from "~/types/application-types";
import LanguageDialog from "~/components/global/LanguageDialog.vue";
import TheSnackbar from "@/components/Layout/LayoutParts/TheSnackbar.vue";
import { useAppInfo } from "~/composables/api";
import { useCookbooks, usePublicCookbooks } from "~/composables/use-group-cookbooks";
import { useCookbookPreferences } from "~/composables/use-users/preferences";
import { useHouseholdStore, usePublicHouseholdStore } from "~/composables/store/use-household-store";
import { useToggleDarkMode } from "~/composables/use-utils";
import { ReadCookBook } from "~/lib/api/types/cookbook";
import { HouseholdSummary } from "~/lib/api/types/household";
export default defineComponent({
components: { AppHeader, AppSidebar, LanguageDialog, TheSnackbar },
Expand All @@ -99,6 +104,15 @@ export default defineComponent({
const route = useRoute();
const groupSlug = computed(() => route.value.params.groupSlug || $auth.user?.groupSlug || "");
const { cookbooks } = isOwnGroup.value ? useCookbooks() : usePublicCookbooks(groupSlug.value || "");
const cookbookPreferences = useCookbookPreferences();
const { store: households } = isOwnGroup.value ? useHouseholdStore() : usePublicHouseholdStore(groupSlug.value || "");
const householdsById = computed(() => {
return households.value.reduce((acc, household) => {
acc[household.id] = household;
return acc;
}, {} as { [key: string]: HouseholdSummary });
});
const appInfo = useAppInfo();
const showImageImport = computed(() => appInfo.value?.enableOpenaiImageServices);
Expand All @@ -113,29 +127,57 @@ export default defineComponent({
sidebar.value = !$vuetify.breakpoint.md;
});
const cookbookLinks = computed(() => {
if (!cookbooks.value) return [];
return cookbooks.value.map((cookbook) => {
return {
key: cookbook.slug,
icon: $globals.icons.pages,
title: cookbook.name,
to: `/g/${groupSlug.value}/cookbooks/${cookbook.slug as string}`,
};
function cookbookAsLink(cookbook: ReadCookBook): SideBarLink {
return {
key: cookbook.slug || "",
icon: $globals.icons.pages,
title: cookbook.name,
to: `/g/${groupSlug.value}/cookbooks/${cookbook.slug || ""}`,
restricted: false,
};
}
const currentUserHouseholdId = computed(() => $auth.user?.householdId);
const cookbookLinks = computed<SideBarLink[]>(() => {
if (!cookbooks.value) {
return [];
}
cookbooks.value.sort((a, b) => (a.position || 0) - (b.position || 0));
const ownLinks: SideBarLink[] = [];
const links: SideBarLink[] = [];
const cookbooksByHousehold = cookbooks.value.reduce((acc, cookbook) => {
const householdName = householdsById.value[cookbook.householdId]?.name || "";
if (!acc[householdName]) {
acc[householdName] = [];
}
acc[householdName].push(cookbook);
return acc;
}, {} as Record<string, ReadCookBook[]>);
Object.entries(cookbooksByHousehold).forEach(([householdName, cookbooks]) => {
if (cookbooks[0].householdId === currentUserHouseholdId.value) {
ownLinks.push(...cookbooks.map(cookbookAsLink));
} else {
links.push({
key: householdName,
icon: $globals.icons.book,
title: householdName,
children: cookbooks.map(cookbookAsLink),
restricted: false,
});
}
});
});
interface Link {
insertDivider: boolean;
icon: string;
title: string;
subtitle: string | null;
to: string;
restricted: boolean;
hide: boolean;
}
links.sort((a, b) => a.title.localeCompare(b.title));
if ($auth.user && cookbookPreferences.value.hideOtherHouseholds) {
return ownLinks;
} else {
return [...ownLinks, ...links];
}
});
const createLinks = computed<Link[]>(() => [
const createLinks = computed<SideBarLink[]>(() => [
{
insertDivider: false,
icon: $globals.icons.link,
Expand Down Expand Up @@ -165,7 +207,7 @@ export default defineComponent({
},
]);
const bottomLinks = computed<SidebarLinks>(() => [
const bottomLinks = computed<SideBarLink[]>(() => [
{
icon: $globals.icons.cog,
title: i18n.tc("general.settings"),
Expand All @@ -174,7 +216,7 @@ export default defineComponent({
},
]);
const topLinks = computed<SidebarLinks>(() => [
const topLinks = computed<SideBarLink[]>(() => [
{
icon: $globals.icons.silverwareForkKnife,
to: `/g/${groupSlug.value}`,
Expand Down
20 changes: 18 additions & 2 deletions frontend/components/Layout/LayoutParts/AppSidebar.vue
Original file line number Diff line number Diff line change
Expand Up @@ -135,7 +135,7 @@
</template>

<script lang="ts">
import { computed, defineComponent, reactive, toRefs, useContext } from "@nuxtjs/composition-api";
import { computed, defineComponent, reactive, toRefs, useContext, watch } from "@nuxtjs/composition-api";
import { useLoggedInState } from "~/composables/use-logged-in-state";
import { SidebarLinks } from "~/types/application-types";
import UserAvatar from "~/components/Domain/User/UserAvatar.vue";
Expand Down Expand Up @@ -192,13 +192,29 @@ export default defineComponent({
const userProfileLink = computed(() => $auth.user ? "/user/profile" : undefined);
const state = reactive({
dropDowns: {},
dropDowns: {} as Record<string, boolean>,
topSelected: null as string[] | null,
secondarySelected: null as string[] | null,
bottomSelected: null as string[] | null,
hasOpenedBefore: false as boolean,
});
const allLinks = computed(() => [...props.topLink, ...(props.secondaryLinks || []), ...(props.bottomLinks || [])]);
function initDropdowns() {
allLinks.value.forEach((link) => {
state.dropDowns[link.title] = link.childrenStartExpanded || false;
})
}
watch(
() => allLinks,
() => {
initDropdowns();
},
{
deep: true,
}
);
return {
...toRefs(state),
userFavoritesLink,
Expand Down
12 changes: 6 additions & 6 deletions frontend/composables/use-group-cookbooks.ts
Original file line number Diff line number Diff line change
Expand Up @@ -99,10 +99,10 @@ export const useCookbooks = function () {

loading.value = false;
},
async createOne() {
async createOne(name: string | null = null) {
loading.value = true;
const { data } = await api.cookbooks.createOne({
name: i18n.t("cookbook.household-cookbook-name", [household.value?.name || "", String((cookbookStore?.value?.length ?? 0) + 1)]) as string,
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: "",
});
Expand All @@ -129,18 +129,18 @@ export const useCookbooks = function () {
return data;
},

async updateOrder() {
if (!cookbookStore?.value) {
async updateOrder(cookbooks: ReadCookBook[]) {
if (!cookbooks?.length) {
return;
}

loading.value = true;

cookbookStore.value.forEach((element, index) => {
cookbooks.forEach((element, index) => {
element.position = index + 1;
});

const { data } = await api.cookbooks.updateAll(cookbookStore.value);
const { data } = await api.cookbooks.updateAll(cookbooks);

if (data && cookbookStore?.value) {
this.refreshAll();
Expand Down
18 changes: 18 additions & 0 deletions frontend/composables/use-users/preferences.ts
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,10 @@ export interface UserParsingPreferences {
parser: RegisteredParser;
}

export interface UserCookbooksPreferences {
hideOtherHouseholds: boolean;
}

export function useUserMealPlanPreferences(): Ref<UserMealPlanPreferences> {
const fromStorage = useLocalStorage(
"meal-planner-preferences",
Expand Down Expand Up @@ -153,3 +157,17 @@ export function useParsingPreferences(): Ref<UserParsingPreferences> {

return fromStorage;
}

export function useCookbookPreferences(): Ref<UserCookbooksPreferences> {
const fromStorage = useLocalStorage(
"cookbook-preferences",
{
hideOtherHouseholds: false,
},
{ mergeDefaults: true }
// we cast to a Ref because by default it will return an optional type ref
// but since we pass defaults we know all properties are set.
) as unknown as Ref<UserCookbooksPreferences>;

return fromStorage;
}
2 changes: 2 additions & 0 deletions frontend/lang/messages/en-US.json
Original file line number Diff line number Diff line change
Expand Up @@ -1327,6 +1327,8 @@
"cookbook": {
"cookbooks": "Cookbooks",
"description": "Cookbooks are another way to organize recipes by creating cross sections of recipes, organizers, and other filters. Creating a cookbook will add an entry to the side-bar and all the recipes with the filters chosen will be displayed in the cookbook.",
"hide-cookbooks-from-other-households": "Hide Cookbooks from Other Households",
"hide-cookbooks-from-other-households-description": "When enabled, only cookbooks from your household will appear on the sidebar",
"public-cookbook": "Public Cookbook",
"public-cookbook-description": "Public Cookbooks can be shared with non-mealie users and will be displayed on your groups page.",
"filter-options": "Filter Options",
Expand Down
Loading

0 comments on commit 782cdcf

Please sign in to comment.