diff --git a/frontend.old/.env.development b/frontend.old/.env.development
deleted file mode 100644
index 4afc44f70ac8..000000000000
--- a/frontend.old/.env.development
+++ /dev/null
@@ -1,2 +0,0 @@
-VUE_APP_API_BASE_URL=http://localhost:9000
-PREVIEW_BUNDLE=true
\ No newline at end of file
diff --git a/frontend.old/README.md b/frontend.old/README.md
deleted file mode 100644
index 576b98091161..000000000000
--- a/frontend.old/README.md
+++ /dev/null
@@ -1,24 +0,0 @@
-# frontend
-
-## Project setup
-```
-npm install
-```
-
-### Compiles and hot-reloads for development
-```
-npm run serve
-```
-
-### Compiles and minifies for production
-```
-npm run build
-```
-
-### Lints and fixes files
-```
-npm run lint
-```
-
-### Customize configuration
-See [Configuration Reference](https://cli.vuejs.org/config/).
diff --git a/frontend.old/babel.config.js b/frontend.old/babel.config.js
deleted file mode 100644
index 162a3ea97c29..000000000000
--- a/frontend.old/babel.config.js
+++ /dev/null
@@ -1,3 +0,0 @@
-module.exports = {
- presets: ["@vue/cli-plugin-babel/preset"],
-};
diff --git a/frontend.old/component-stagin/Domain/MealPlan/MealPlanCard.vue b/frontend.old/component-stagin/Domain/MealPlan/MealPlanCard.vue
deleted file mode 100644
index 140e9872cb39..000000000000
--- a/frontend.old/component-stagin/Domain/MealPlan/MealPlanCard.vue
+++ /dev/null
@@ -1,173 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- {{ $globals.icons.edit }}
-
- {{ $t("reicpe.no-recipe") }}
-
-
-
-
-
-
- {{ $d(new Date(planDay.date.replaceAll("-", "/")), "short") }}
-
- {{ planDay.meals[0].name }}
-
-
-
-
-
-
- {{ $globals.icons.edit }}
-
- {{ $t("reicpe.no-recipe") }}
-
-
-
-
- {{ $globals.icons.create }}
-
- {{ $t("meal-plan.side") }}
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- {{ $globals.icons.delete }}
-
-
-
-
-
-
-
-
-
-
-
-
-
-
diff --git a/frontend.old/component-stagin/Domain/MealPlan/MealPlanEditor.vue b/frontend.old/component-stagin/Domain/MealPlan/MealPlanEditor.vue
deleted file mode 100644
index 7f790b483491..000000000000
--- a/frontend.old/component-stagin/Domain/MealPlan/MealPlanEditor.vue
+++ /dev/null
@@ -1,46 +0,0 @@
-
-
-
- {{ $t("meal-plan.edit-meal-plan") }}
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
diff --git a/frontend.old/component-stagin/Domain/MealPlan/MealPlanNew.vue b/frontend.old/component-stagin/Domain/MealPlan/MealPlanNew.vue
deleted file mode 100644
index fd8fbe347ec2..000000000000
--- a/frontend.old/component-stagin/Domain/MealPlan/MealPlanNew.vue
+++ /dev/null
@@ -1,227 +0,0 @@
-
-
-
- {{ $t("meal-plan.create-a-new-meal-plan") }}
-
- {{ $globals.icons.calendarMinus }}
- {{ $t("meal-plan.quick-week") }}
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- {{ $globals.icons.diceMultiple }}
-
- {{ $t("general.random") }}
-
-
-
-
-
-
-
-
diff --git a/frontend.old/component-stagin/Domain/User/UserAvatar.vue b/frontend.old/component-stagin/Domain/User/UserAvatar.vue
deleted file mode 100644
index a2f119084b25..000000000000
--- a/frontend.old/component-stagin/Domain/User/UserAvatar.vue
+++ /dev/null
@@ -1,61 +0,0 @@
-
-
-
-
-
- {{ initials }}
-
-
-
-
- {{ user.fullName }}
- {{ user.admin ? $t("user.admin") : $t("user.user") }}
-
-
-
-
-
-
-
\ No newline at end of file
diff --git a/frontend.old/component-stagin/Page/Recipe/RecipeEditor.vue b/frontend.old/component-stagin/Page/Recipe/RecipeEditor.vue
deleted file mode 100644
index 65ab9152a3ef..000000000000
--- a/frontend.old/component-stagin/Page/Recipe/RecipeEditor.vue
+++ /dev/null
@@ -1,153 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- {{ $t("recipe.categories") }}
-
-
-
-
-
-
-
-
-
- {{ $t("tag.tags") }}
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- {{ $globals.icons.create }}
-
-
-
-
-
-
-
-
-
-
-
-
-
-
diff --git a/frontend.old/component-stagin/Page/Recipe/RecipeViewer.vue b/frontend.old/component-stagin/Page/Recipe/RecipeViewer.vue
deleted file mode 100644
index c06b9a0cca14..000000000000
--- a/frontend.old/component-stagin/Page/Recipe/RecipeViewer.vue
+++ /dev/null
@@ -1,142 +0,0 @@
-
-
-
- {{ recipe.name }}
-
-
-
-
-
-
- {{ recipe.recipeYield }}
-
-
-
-
-
-
-
-
-
-
- {{ $t("recipe.categories") }}
-
-
-
-
-
-
-
-
- {{ $t("tag.tags") }}
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- {{ $t("recipe.original-url") }}
-
-
-
-
-
-
-
-
-
diff --git a/frontend.old/frontend.Dockerfile b/frontend.old/frontend.Dockerfile
deleted file mode 100644
index 2cdab5876dc9..000000000000
--- a/frontend.old/frontend.Dockerfile
+++ /dev/null
@@ -1,22 +0,0 @@
-FROM node:lts-alpine
-
-# # install simple http server for serving static content
-# RUN npm install -g http-server
-
-# make the 'app' folder the current working directory
-WORKDIR /app
-
-# copy both 'package.json' and 'package-lock.json' (if available)
-COPY package*.json ./
-
-# install project dependencies
-RUN npm install
-
-# copy project files and folders to the current working directory (i.e. 'app' folder)
-# COPY . .
-
-# build app for production with minification
-# RUN npm run build
-
-EXPOSE 8080
-CMD [ "npm", "run", "serve" ]
\ No newline at end of file
diff --git a/frontend.old/jsconfig.json b/frontend.old/jsconfig.json
deleted file mode 100644
index 0486e3bb36a6..000000000000
--- a/frontend.old/jsconfig.json
+++ /dev/null
@@ -1,9 +0,0 @@
-{
- "compilerOptions": {
- "baseUrl": ".",
- "paths": {
- "@/*": ["./src/*"]
- }
- },
- "exclude": ["node_modules", "dist"]
-}
diff --git a/frontend.old/package.json b/frontend.old/package.json
deleted file mode 100644
index 1384c5140725..000000000000
--- a/frontend.old/package.json
+++ /dev/null
@@ -1,75 +0,0 @@
-{
- "name": "frontend",
- "version": "0.1.0",
- "private": true,
- "scripts": {
- "serve": "vue-cli-service serve",
- "build": "vue-cli-service build",
- "lint": "vue-cli-service lint",
- "i18n:report": "vue-cli-service i18n:report --src './src/**/*.?(js|vue)' --locales './src/locales/**/*.json'"
- },
- "dependencies": {
- "@adapttive/vue-markdown": "^4.0.1",
- "axios": "^0.21.1",
- "core-js": "^3.14.0",
- "fuse.js": "^6.4.6",
- "register-service-worker": "^1.7.1",
- "v-jsoneditor": "^1.4.4",
- "vue": "^2.6.14",
- "vue-i18n": "^8.24.1",
- "vue-router": "^3.5.1",
- "vuedraggable": "^2.24.3",
- "vuetify": "^2.5.3",
- "vuex": "^3.6.2",
- "vuex-persistedstate": "^4.0.0-beta.3"
- },
- "devDependencies": {
- "@intlify/vue-i18n-loader": "^1.1.0",
- "@mdi/font": "^5.9.55",
- "@mdi/js": "^5.9.55",
- "@vue/cli-plugin-babel": "^4.5.13",
- "@vue/cli-plugin-eslint": "^4.5.13",
- "@vue/cli-plugin-pwa": "~4.5.0",
- "@vue/cli-service": "^4.5.13",
- "@vue/preload-webpack-plugin": "^2.0.0",
- "babel-eslint": "^10.1.0",
- "eslint": "^6.7.2",
- "eslint-plugin-vue": "^6.2.2",
- "html-webpack-plugin": "^5.3.1",
- "preload-webpack-plugin": "^2.3.0",
- "sass": "^1.34.1",
- "sass-loader": "^8.0.2",
- "typeface-roboto": "^1.1.13",
- "vue-cli-plugin-i18n": "~1.0.1",
- "vue-cli-plugin-vuetify": "^2.4.1",
- "vue-cli-plugin-webpack-bundle-analyzer": "^4.0.0",
- "vue-template-compiler": "^2.6.14",
- "vuetify-loader": "^1.7.2"
- },
- "eslintConfig": {
- "root": true,
- "env": {
- "node": true
- },
- "extends": [
- "plugin:vue/essential",
- "eslint:recommended"
- ],
- "parserOptions": {
- "parser": "babel-eslint"
- },
- "rules": {}
- },
- "prettier": {
- "trailingComma": "es5",
- "tabWidth": 2,
- "semi": true,
- "singleQuote": false,
- "printWidth": 120
- },
- "browserslist": [
- "> 1%",
- "last 2 versions",
- "not dead"
- ]
-}
\ No newline at end of file
diff --git a/frontend.old/public/img/icons/android-chrome-192x192.png b/frontend.old/public/img/icons/android-chrome-192x192.png
deleted file mode 100644
index 0569b776e427..000000000000
Binary files a/frontend.old/public/img/icons/android-chrome-192x192.png and /dev/null differ
diff --git a/frontend.old/public/img/icons/android-chrome-maskable-192x192.png b/frontend.old/public/img/icons/android-chrome-maskable-192x192.png
deleted file mode 100644
index 0569b776e427..000000000000
Binary files a/frontend.old/public/img/icons/android-chrome-maskable-192x192.png and /dev/null differ
diff --git a/frontend.old/public/img/icons/android-chrome-maskable-512x512.png b/frontend.old/public/img/icons/android-chrome-maskable-512x512.png
deleted file mode 100644
index cb0380533224..000000000000
Binary files a/frontend.old/public/img/icons/android-chrome-maskable-512x512.png and /dev/null differ
diff --git a/frontend.old/public/img/icons/apple-touch-icon-120x120.png b/frontend.old/public/img/icons/apple-touch-icon-120x120.png
deleted file mode 100644
index 0bb475552c3c..000000000000
Binary files a/frontend.old/public/img/icons/apple-touch-icon-120x120.png and /dev/null differ
diff --git a/frontend.old/public/img/icons/apple-touch-icon-152x152.png b/frontend.old/public/img/icons/apple-touch-icon-152x152.png
deleted file mode 100644
index 53d2b9201a40..000000000000
Binary files a/frontend.old/public/img/icons/apple-touch-icon-152x152.png and /dev/null differ
diff --git a/frontend.old/public/img/icons/apple-touch-icon-180x180.png b/frontend.old/public/img/icons/apple-touch-icon-180x180.png
deleted file mode 100644
index 12ee3c053603..000000000000
Binary files a/frontend.old/public/img/icons/apple-touch-icon-180x180.png and /dev/null differ
diff --git a/frontend.old/public/img/icons/apple-touch-icon-60x60.png b/frontend.old/public/img/icons/apple-touch-icon-60x60.png
deleted file mode 100644
index 772375179bb6..000000000000
Binary files a/frontend.old/public/img/icons/apple-touch-icon-60x60.png and /dev/null differ
diff --git a/frontend.old/public/img/icons/apple-touch-icon-76x76.png b/frontend.old/public/img/icons/apple-touch-icon-76x76.png
deleted file mode 100644
index 919cbdeb6985..000000000000
Binary files a/frontend.old/public/img/icons/apple-touch-icon-76x76.png and /dev/null differ
diff --git a/frontend.old/public/img/icons/apple-touch-icon.png b/frontend.old/public/img/icons/apple-touch-icon.png
deleted file mode 100644
index 12ee3c053603..000000000000
Binary files a/frontend.old/public/img/icons/apple-touch-icon.png and /dev/null differ
diff --git a/frontend.old/public/img/icons/favicon-16x16.png b/frontend.old/public/img/icons/favicon-16x16.png
deleted file mode 100644
index 05e2e7625d46..000000000000
Binary files a/frontend.old/public/img/icons/favicon-16x16.png and /dev/null differ
diff --git a/frontend.old/public/img/icons/favicon-32x32.png b/frontend.old/public/img/icons/favicon-32x32.png
deleted file mode 100644
index 9263cc67c9c4..000000000000
Binary files a/frontend.old/public/img/icons/favicon-32x32.png and /dev/null differ
diff --git a/frontend.old/public/img/icons/msapplication-icon-144x144.png b/frontend.old/public/img/icons/msapplication-icon-144x144.png
deleted file mode 100644
index c4a5fcb71b59..000000000000
Binary files a/frontend.old/public/img/icons/msapplication-icon-144x144.png and /dev/null differ
diff --git a/frontend.old/public/img/icons/mstile-150x150.png b/frontend.old/public/img/icons/mstile-150x150.png
deleted file mode 100644
index c6dfc5414f9b..000000000000
Binary files a/frontend.old/public/img/icons/mstile-150x150.png and /dev/null differ
diff --git a/frontend.old/public/img/icons/safari-pinned-tab.svg b/frontend.old/public/img/icons/safari-pinned-tab.svg
deleted file mode 100644
index 802178d07502..000000000000
--- a/frontend.old/public/img/icons/safari-pinned-tab.svg
+++ /dev/null
@@ -1,3 +0,0 @@
-
\ No newline at end of file
diff --git a/frontend.old/public/index.html b/frontend.old/public/index.html
deleted file mode 100644
index fa926f2b96ea..000000000000
--- a/frontend.old/public/index.html
+++ /dev/null
@@ -1,22 +0,0 @@
-
-
-
-
-
-
-
-
-
- Mealie
-
-
-
-
-
-
-
-
-
\ No newline at end of file
diff --git a/frontend.old/src/App.vue b/frontend.old/src/App.vue
deleted file mode 100644
index 63d1c45e1549..000000000000
--- a/frontend.old/src/App.vue
+++ /dev/null
@@ -1,138 +0,0 @@
-
-
-
-
-
-
-
- This is a Demo of the v0.5.0 (BETA) | Username: changeme@email.com | Password: demo
-
-
-
-
- {{ snackWithBtnText }}
-
-
- {{ snackBtnText }}
-
-
- {{ $globals.icons.close }}
-
-
-
-
-
-
-
-
-
-
-
-
diff --git a/frontend.old/src/api/about.js b/frontend.old/src/api/about.js
deleted file mode 100644
index 92434fad1311..000000000000
--- a/frontend.old/src/api/about.js
+++ /dev/null
@@ -1,80 +0,0 @@
-import { apiReq } from "./api-utils";
-import i18n from "@/i18n.js";
-import { API_ROUTES } from "./apiRoutes";
-
-export const aboutAPI = {
- async getEvents() {
- const resposne = await apiReq.get(API_ROUTES.aboutEvents);
- return resposne.data;
- },
- async deleteEvent(id) {
- const resposne = await apiReq.delete(API_ROUTES.aboutEventsId(id));
- return resposne.data;
- },
- async deleteAllEvents() {
- const resposne = await apiReq.delete(API_ROUTES.aboutEvents);
- return resposne.data;
- },
-
- async allEventNotifications() {
- const response = await apiReq.get(API_ROUTES.aboutEventsNotifications);
- return response.data;
- },
-
- async createNotification(data) {
- const response = await apiReq.post(API_ROUTES.aboutEventsNotifications, data);
- return response.data;
- },
-
- async deleteNotification(id) {
- const response = await apiReq.delete(API_ROUTES.aboutEventsNotificationsId(id));
- return response.data;
- },
- async testNotificationByID(id) {
- const response = await apiReq.post(
- API_ROUTES.aboutEventsNotificationsTest,
- { id: id },
- () => i18n.t("events.something-went-wrong"),
- () => i18n.t("events.test-message-sent")
- );
- return response.data;
- },
- async testNotificationByURL(url) {
- const response = await apiReq.post(
- API_ROUTES.aboutEventsNotificationsTest,
- { test_url: url },
- () => i18n.t("events.something-went-wrong"),
- () => i18n.t("events.test-message-sent")
- );
- return response.data;
- },
- // async getAppInfo() {
- // const response = await apiReq.get(aboutURLs.version);
- // return response.data;
- // },
-
- // async getDebugInfo() {
- // const response = await apiReq.get(aboutURLs.debug);
- // return response.data;
- // },
-
- // async getLogText(num) {
- // const response = await apiReq.get(aboutURLs.log(num));
- // return response.data;
- // },
-
- // async getLastJson() {
- // const response = await apiReq.get(aboutURLs.lastRecipe);
- // return response.data;
- // },
-
- // async getIsDemo() {
- // const response = await apiReq.get(aboutURLs.demo);
- // return response.data;
- // },
-
- // async getStatistics() {
- // const response = await apiReq.get(aboutURLs.statistics);
- // return response.data;
- // },
-};
diff --git a/frontend.old/src/api/api-utils.js b/frontend.old/src/api/api-utils.js
deleted file mode 100644
index 2a9b0acb4a85..000000000000
--- a/frontend.old/src/api/api-utils.js
+++ /dev/null
@@ -1,121 +0,0 @@
-import { prefix } from "./apiRoutes";
-import axios from "axios";
-import { store } from "../store";
-import { utils } from "@/utils";
-
-axios.defaults.headers.common["Authorization"] = `Bearer ${store.getters.getToken}`;
-
-function handleError(error, getText) {
- if (getText) {
- utils.notify.error(getText(error.response));
- }
- return false;
-}
-function handleResponse(response, getText) {
- if (response && getText) {
- const successText = getText(response);
- utils.notify.success(successText);
- }
- return response;
-}
-
-function defaultErrorText(response) {
- return response.statusText;
-}
-
-function defaultSuccessText(response) {
- return response.statusText;
-}
-
-const requests = {
- /**
- *
- * @param {*} funcCall Callable Axios Function
- * @param {*} url Destination url
- * @param {*} data Request Data
- * @param {*} getErrorText Error Text Function
- * @param {*} getSuccessText Success Text Function
- * @returns Object response
- */
- unsafe: async function(funcCall, url, data, getErrorText = defaultErrorText, getSuccessText) {
- const response = await funcCall(url, data).catch(function(error) {
- handleError(error, getErrorText);
- });
- return handleResponse(response, getSuccessText);
- },
- /**
- *
- * @param {*} funcCall Callable Axios Function
- * @param {*} url Destination url
- * @param {*} data Request Data
- * @param {*} getErrorText Error Text Function
- * @param {*} getSuccessText Success Text Function
- * @returns Array [response, error]
- */
- safe: async function(funcCall, url, data, getErrorText = defaultErrorText, getSuccessText) {
- const response = await funcCall(url, data).catch(function(error) {
- handleError(error, getErrorText);
- return [null, error];
- });
- return [handleResponse(response, getSuccessText), null];
- },
-};
-
-const apiReq = {
- get: async function(url, getErrorText = defaultErrorText) {
- return axios.get(url).catch(function(error) {
- handleError(error, getErrorText);
- });
- },
-
- getSafe: async function(url) {
- let error = null;
- const response = await axios.get(url).catch(e => {
- error = e;
- });
- return [response, error];
- },
-
- post: async function(url, data, getErrorText = defaultErrorText, getSuccessText) {
- return await requests.unsafe(axios.post, url, data, getErrorText, getSuccessText);
- },
-
- postSafe: async function(url, data, getErrorText = defaultErrorText, getSuccessText) {
- return await requests.safe(axios.post, url, data, getErrorText, getSuccessText);
- },
-
- put: async function(url, data, getErrorText = defaultErrorText, getSuccessText) {
- return await requests.unsafe(axios.put, url, data, getErrorText, getSuccessText);
- },
-
- putSafe: async function(url, data, getErrorText = defaultErrorText, getSuccessText) {
- return await requests.safe(axios.put, url, data, getErrorText, getSuccessText);
- },
-
- patch: async function(url, data, getErrorText = defaultErrorText, getSuccessText) {
- return await requests.unsafe(axios.patch, url, data, getErrorText, getSuccessText);
- },
-
- patchSafe: async function(url, data, getErrorText = defaultErrorText, getSuccessText) {
- return await requests.safe(axios.patch, url, data, getErrorText, getSuccessText);
- },
-
- delete: async function(url, data, getErrorText = defaultErrorText, getSuccessText = defaultSuccessText) {
- return await requests.unsafe(axios.delete, url, data, getErrorText, getSuccessText);
- },
-
- deleteSafe: async function(url, data, getErrorText = defaultErrorText, getSuccessText = defaultSuccessText) {
- return await requests.unsafe(axios.delete, url, data, getErrorText, getSuccessText);
- },
-
- download: async function(url) {
- const response = await this.get(url);
- const token = response.data.fileToken;
-
- const tokenURL = prefix + "/utils/download?token=" + token;
- window.open(tokenURL, "_blank");
- return response.data;
- },
-};
-
-export { apiReq };
diff --git a/frontend.old/src/api/apiRoutes.js b/frontend.old/src/api/apiRoutes.js
deleted file mode 100644
index 5d726267743f..000000000000
--- a/frontend.old/src/api/apiRoutes.js
+++ /dev/null
@@ -1,90 +0,0 @@
-// This Content is Auto Generated
-export const prefix = "/api";
-export const API_ROUTES = {
- aboutEvents: `${prefix}/about/events`,
- aboutEventsNotifications: `${prefix}/about/events/notifications`,
- aboutEventsNotificationsTest: `${prefix}/about/events/notifications/test`,
- aboutRecipesDefaults: `${prefix}/about/recipes/defaults`,
- authRefresh: `${prefix}/auth/refresh`,
- authToken: `${prefix}/auth/token`,
- authTokenLong: `${prefix}/auth/token/long`,
- backupsAvailable: `${prefix}/backups/available`,
- backupsExportDatabase: `${prefix}/backups/export/database`,
- backupsUpload: `${prefix}/backups/upload`,
- categories: `${prefix}/categories`,
- categoriesEmpty: `${prefix}/categories/empty`,
- debug: `${prefix}/debug`,
- debugLastRecipeJson: `${prefix}/debug/last-recipe-json`,
- debugLog: `${prefix}/debug/log`,
- debugStatistics: `${prefix}/debug/statistics`,
- debugVersion: `${prefix}/debug/version`,
- groups: `${prefix}/groups`,
- groupsSelf: `${prefix}/groups/self`,
- mealPlansAll: `${prefix}/meal-plans/all`,
- mealPlansCreate: `${prefix}/meal-plans/create`,
- mealPlansThisWeek: `${prefix}/meal-plans/this-week`,
- mealPlansToday: `${prefix}/meal-plans/today`,
- mealPlansTodayImage: `${prefix}/meal-plans/today/image`,
- migrations: `${prefix}/migrations`,
- recipesCategory: `${prefix}/recipes/category`,
- recipesCreate: `${prefix}/recipes/create`,
- recipesCreateFromZip: `${prefix}/recipes/create-from-zip`,
- recipesCreateUrl: `${prefix}/recipes/create-url`,
- recipesSummary: `${prefix}/recipes/summary`,
- recipesSummaryUncategorized: `${prefix}/recipes/summary/uncategorized`,
- recipesSummaryUntagged: `${prefix}/recipes/summary/untagged`,
- recipesTag: `${prefix}/recipes/tag`,
- recipesTestScrapeUrl: `${prefix}/recipes/test-scrape-url`,
- shoppingLists: `${prefix}/shopping-lists`,
- siteSettings: `${prefix}/site-settings`,
- siteSettingsCustomPages: `${prefix}/site-settings/custom-pages`,
- siteSettingsWebhooksTest: `${prefix}/site-settings/webhooks/test`,
- tags: `${prefix}/tags`,
- tagsEmpty: `${prefix}/tags/empty`,
- themes: `${prefix}/themes`,
- themesCreate: `${prefix}/themes/create`,
- users: `${prefix}/users`,
- usersApiTokens: `${prefix}/users/api-tokens`,
- usersSelf: `${prefix}/users/self`,
- usersSignUps: `${prefix}/users/sign-ups`,
- utilsDownload: `${prefix}/utils/download`,
-
- aboutEventsId: id => `${prefix}/about/events/${id}`,
- aboutEventsNotificationsId: id => `${prefix}/about/events/notifications/${id}`,
- backupsFileNameDelete: file_name => `${prefix}/backups/${file_name}/delete`,
- backupsFileNameDownload: file_name => `${prefix}/backups/${file_name}/download`,
- backupsFileNameImport: file_name => `${prefix}/backups/${file_name}/import`,
- categoriesCategory: category => `${prefix}/categories/${category}`,
- debugLogNum: num => `${prefix}/debug/log/${num}`,
- groupsId: id => `${prefix}/groups/${id}`,
- mealPlansId: id => `${prefix}/meal-plans/${id}`,
- mealPlansIdShoppingList: id => `${prefix}/meal-plans/${id}/shopping-list`,
- mealPlansPlanId: plan_id => `${prefix}/meal-plans/${plan_id}`,
- mediaRecipesRecipeSlugAssetsFileName: (recipe_slug, file_name) =>
- `${prefix}/media/recipes/${recipe_slug}/assets/${file_name}`,
- mediaRecipesRecipeSlugImagesFileName: (recipe_slug, file_name) =>
- `${prefix}/media/recipes/${recipe_slug}/images/${file_name}`,
- migrationsImportTypeFileNameDelete: (import_type, file_name) =>
- `${prefix}/migrations/${import_type}/${file_name}/delete`,
- migrationsImportTypeFileNameImport: (import_type, file_name) =>
- `${prefix}/migrations/${import_type}/${file_name}/import`,
- migrationsImportTypeUpload: import_type => `${prefix}/migrations/${import_type}/upload`,
- recipesRecipeSlug: recipe_slug => `${prefix}/recipes/${recipe_slug}`,
- recipesRecipeSlugAssets: recipe_slug => `${prefix}/recipes/${recipe_slug}/assets`,
- recipesRecipeSlugImage: recipe_slug => `${prefix}/recipes/${recipe_slug}/image`,
- recipesRecipeSlugZip: recipe_slug => `${prefix}/recipes/${recipe_slug}/zip`,
- recipesSlugComments: slug => `${prefix}/recipes/${slug}/comments`,
- recipesSlugCommentsId: (slug, id) => `${prefix}/recipes/${slug}/comments/${id}`,
- shoppingListsId: id => `${prefix}/shopping-lists/${id}`,
- siteSettingsCustomPagesId: id => `${prefix}/site-settings/custom-pages/${id}`,
- tagsTag: tag => `${prefix}/tags/${tag}`,
- themesId: id => `${prefix}/themes/${id}`,
- usersApiTokensTokenId: token_id => `${prefix}/users/api-tokens/${token_id}`,
- usersId: id => `${prefix}/users/${id}`,
- usersIdFavorites: id => `${prefix}/users/${id}/favorites`,
- usersIdFavoritesSlug: (id, slug) => `${prefix}/users/${id}/favorites/${slug}`,
- usersIdImage: id => `${prefix}/users/${id}/image`,
- usersIdPassword: id => `${prefix}/users/${id}/password`,
- usersIdResetPassword: id => `${prefix}/users/${id}/reset-password`,
- usersSignUpsToken: token => `${prefix}/users/sign-ups/${token}`,
-};
diff --git a/frontend.old/src/api/backup.js b/frontend.old/src/api/backup.js
deleted file mode 100644
index 31c354c07e9d..000000000000
--- a/frontend.old/src/api/backup.js
+++ /dev/null
@@ -1,62 +0,0 @@
-import { apiReq } from "./api-utils";
-import { store } from "@/store";
-import i18n from "@/i18n.js";
-import { API_ROUTES } from "./apiRoutes";
-
-export const backupAPI = {
- /**
- * Request all backups available on the server
- * @returns {Array} List of Available Backups
- */
- async requestAvailable() {
- let response = await apiReq.get(API_ROUTES.backupsAvailable);
- return response.data;
- },
- /**
- * Calls for importing a file on the server
- * @param {string} fileName
- * @param {object} data
- * @returns A report containing status of imported items
- */
- async import(fileName, data) {
- let response = await apiReq.post(API_ROUTES.backupsFileNameImport(fileName), data);
- store.dispatch("requestRecentRecipes");
- return response;
- },
- /**
- * Removes a file from the server
- * @param {string} fileName
- */
- async delete(fileName) {
- return apiReq.delete(
- API_ROUTES.backupsFileNameDelete(fileName),
- null,
- () => i18n.t("settings.backup.unable-to-delete-backup"),
- () => i18n.t("settings.backup.backup-deleted")
- );
- },
- /**
- * Creates a backup on the serve given a set of options
- * @param {object} data
- * @returns
- */
- async create(options) {
- return apiReq.post(
- API_ROUTES.backupsExportDatabase,
- options,
- () => i18n.t("settings.backup.error-creating-backup-see-log-file"),
- response => {
- return i18n.t("settings.backup.backup-created-at-response-export_path", { path: response.data.export_path });
- }
- );
- },
- /**
- * Downloads a file from the server. I don't actually think this is used?
- * @param {string} fileName
- * @returns Download URL
- */
- async download(fileName) {
- const url = API_ROUTES.backupsFileNameDownload(fileName);
- apiReq.download(url);
- },
-};
diff --git a/frontend.old/src/api/category.js b/frontend.old/src/api/category.js
deleted file mode 100644
index d06d4b5b3932..000000000000
--- a/frontend.old/src/api/category.js
+++ /dev/null
@@ -1,111 +0,0 @@
-import { apiReq } from "./api-utils";
-import { store } from "@/store";
-import i18n from "@/i18n.js";
-import { API_ROUTES } from "./apiRoutes";
-
-export const categoryAPI = {
- async getAll() {
- let response = await apiReq.get(API_ROUTES.categories);
- return response.data;
- },
- async getEmpty() {
- let response = await apiReq.get(API_ROUTES.categoriesEmpty);
- return response.data;
- },
- async create(name) {
- const response = await apiReq.post(
- API_ROUTES.categories,
- { name: name },
- () => i18n.t("category.category-creation-failed"),
- () => i18n.t("category.category-created")
- );
- if (response) {
- store.dispatch("requestCategories");
- return response.data;
- }
- },
- async getRecipesInCategory(category) {
- let response = await apiReq.get(API_ROUTES.categoriesCategory(category));
- return response.data;
- },
- async update(name, newName, overrideRequest = false) {
- const response = await apiReq.put(
- API_ROUTES.categoriesCategory(name),
- { name: newName },
- () => i18n.t("category.category-update-failed"),
- () => i18n.t("category.category-updated")
- );
- if (response && !overrideRequest) {
- store.dispatch("requestCategories");
- return response.data;
- }
- },
- async delete(category, overrideRequest = false) {
- const response = await apiReq.delete(
- API_ROUTES.categoriesCategory(category),
- null,
- () => i18n.t("category.category-deletion-failed"),
- () => i18n.t("category.category-deleted")
- );
- if (response && !overrideRequest) {
- store.dispatch("requestCategories");
- }
- return response;
- },
-};
-
-export const tagAPI = {
- async getAll() {
- let response = await apiReq.get(API_ROUTES.tags);
- return response.data;
- },
- async getEmpty() {
- let response = await apiReq.get(API_ROUTES.tagsEmpty);
- return response.data;
- },
- async create(name) {
- const response = await apiReq.post(
- API_ROUTES.tags,
- { name: name },
- () => i18n.t("tag.tag-creation-failed"),
- () => i18n.t("tag.tag-created")
- );
- if (response) {
- store.dispatch("requestTags");
- return response.data;
- }
- },
- async getRecipesInTag(tag) {
- let response = await apiReq.get(API_ROUTES.tagsTag(tag));
- return response.data;
- },
- async update(name, newName, overrideRequest = false) {
- const response = await apiReq.put(
- API_ROUTES.tagsTag(name),
- { name: newName },
- () => i18n.t("tag.tag-update-failed"),
- () => i18n.t("tag.tag-updated")
- );
-
- if (response) {
- if (!overrideRequest) {
- store.dispatch("requestTags");
- }
- return response.data;
- }
- },
- async delete(tag, overrideRequest = false) {
- const response = await apiReq.delete(
- API_ROUTES.tagsTag(tag),
- null,
- () => i18n.t("tag.tag-deletion-failed"),
- () => i18n.t("tag.tag-deleted")
- );
- if (response) {
- if (!overrideRequest) {
- store.dispatch("requestTags");
- }
- return response.data;
- }
- },
-};
diff --git a/frontend.old/src/api/groups.js b/frontend.old/src/api/groups.js
deleted file mode 100644
index 62ad406b3b43..000000000000
--- a/frontend.old/src/api/groups.js
+++ /dev/null
@@ -1,53 +0,0 @@
-import { apiReq } from "./api-utils";
-import i18n from "@/i18n.js";
-import { API_ROUTES } from "./apiRoutes";
-
-function deleteErrorText(response) {
- switch (response.data.detail) {
- case "GROUP_WITH_USERS":
- return i18n.t("group.cannot-delete-group-with-users");
-
- case "GROUP_NOT_FOUND":
- return i18n.t("group.group-not-found");
-
- case "DEFAULT_GROUP":
- return i18n.t("group.cannot-delete-default-group");
-
- default:
- return i18n.t("group.group-deletion-failed");
- }
-}
-
-export const groupAPI = {
- async allGroups() {
- let response = await apiReq.get(API_ROUTES.groups);
- return response.data;
- },
- create(name) {
- return apiReq.post(
- API_ROUTES.groups,
- { name: name },
- () => i18n.t("group.user-group-creation-failed"),
- () => i18n.t("group.user-group-created")
- );
- },
- delete(id) {
- return apiReq.delete(API_ROUTES.groupsId(id), null, deleteErrorText, function() {
- return i18n.t("group.group-deleted");
- });
- },
- async current() {
- const response = await apiReq.get(API_ROUTES.groupsSelf, null, null);
- if (response) {
- return response.data;
- }
- },
- update(data) {
- return apiReq.put(
- API_ROUTES.groupsId(data.id),
- data,
- () => i18n.t("group.error-updating-group"),
- () => i18n.t("settings.group-settings-updated")
- );
- },
-};
diff --git a/frontend.old/src/api/index.js b/frontend.old/src/api/index.js
deleted file mode 100644
index dbc633212f33..000000000000
--- a/frontend.old/src/api/index.js
+++ /dev/null
@@ -1,37 +0,0 @@
-import { backupAPI } from "./backup";
-import { recipeAPI } from "./recipe";
-import { mealplanAPI } from "./mealplan";
-import { settingsAPI } from "./settings";
-import { themeAPI } from "./themes";
-import { migrationAPI } from "./migration";
-import { utilsAPI } from "./upload";
-import { categoryAPI, tagAPI } from "./category";
-import { metaAPI } from "./meta";
-import { userAPI } from "./users";
-import { signupAPI } from "./signUps";
-import { groupAPI } from "./groups";
-import { siteSettingsAPI } from "./siteSettings";
-import { aboutAPI } from "./about";
-import { shoppingListsAPI } from "./shoppingLists";
-
-/**
- * The main object namespace for interacting with the backend database
- */
-export const api = {
- recipes: recipeAPI,
- siteSettings: siteSettingsAPI,
- backups: backupAPI,
- mealPlans: mealplanAPI,
- settings: settingsAPI,
- themes: themeAPI,
- migrations: migrationAPI,
- utils: utilsAPI,
- categories: categoryAPI,
- tags: tagAPI,
- meta: metaAPI,
- users: userAPI,
- signUps: signupAPI,
- groups: groupAPI,
- about: aboutAPI,
- shoppingLists: shoppingListsAPI,
-};
diff --git a/frontend.old/src/api/mealplan.js b/frontend.old/src/api/mealplan.js
deleted file mode 100644
index f1e3dc8d219e..000000000000
--- a/frontend.old/src/api/mealplan.js
+++ /dev/null
@@ -1,57 +0,0 @@
-import { apiReq } from "./api-utils";
-import i18n from "@/i18n.js";
-import { API_ROUTES } from "./apiRoutes";
-
-export const mealplanAPI = {
- create(postBody) {
- return apiReq.post(
- API_ROUTES.mealPlansCreate,
- postBody,
- () => i18n.t("meal-plan.mealplan-creation-failed"),
- () => i18n.t("meal-plan.mealplan-created")
- );
- },
-
- async all() {
- let response = await apiReq.get(API_ROUTES.mealPlansAll);
- return response;
- },
-
- async thisWeek() {
- let response = await apiReq.get(API_ROUTES.mealPlansThisWeek);
- return response.data;
- },
-
- async today() {
- let response = await apiReq.get(API_ROUTES.mealPlansToday);
- return response;
- },
-
- async getById(id) {
- let response = await apiReq.get(API_ROUTES.mealPlansId(id));
- return response.data;
- },
-
- delete(id) {
- return apiReq.delete(
- API_ROUTES.mealPlansId(id),
- null,
- () => i18n.t("meal-plan.mealplan-deletion-failed"),
- () => i18n.t("meal-plan.mealplan-deleted")
- );
- },
-
- update(id, body) {
- return apiReq.put(
- API_ROUTES.mealPlansId(id),
- body,
- () => i18n.t("meal-plan.mealplan-update-failed"),
- () => i18n.t("meal-plan.mealplan-updated")
- );
- },
-
- async shoppingList(id) {
- let response = await apiReq.get(API_ROUTES.mealPlansIdShoppingList(id));
- return response.data;
- },
-};
diff --git a/frontend.old/src/api/meta.js b/frontend.old/src/api/meta.js
deleted file mode 100644
index b460c961c17a..000000000000
--- a/frontend.old/src/api/meta.js
+++ /dev/null
@@ -1,29 +0,0 @@
-import { apiReq } from "./api-utils";
-import { API_ROUTES } from "./apiRoutes";
-
-export const metaAPI = {
- async getAppInfo() {
- const response = await apiReq.get(API_ROUTES.debugVersion);
- return response.data;
- },
-
- async getDebugInfo() {
- const response = await apiReq.get(API_ROUTES.debug);
- return response.data;
- },
-
- async getLogText(num) {
- const response = await apiReq.get(API_ROUTES.debugLogNum(num));
- return response.data;
- },
-
- async getLastJson() {
- const response = await apiReq.get(API_ROUTES.debugLastRecipeJson);
- return response.data;
- },
-
- async getStatistics() {
- const response = await apiReq.get(API_ROUTES.debugStatistics);
- return response.data;
- },
-};
diff --git a/frontend.old/src/api/migration.js b/frontend.old/src/api/migration.js
deleted file mode 100644
index 96d148a88e64..000000000000
--- a/frontend.old/src/api/migration.js
+++ /dev/null
@@ -1,25 +0,0 @@
-import { apiReq } from "./api-utils";
-import { store } from "../store";
-import i18n from "@/i18n.js";
-import { API_ROUTES } from "./apiRoutes";
-
-export const migrationAPI = {
- async getMigrations() {
- let response = await apiReq.get(API_ROUTES.migrations);
- return response.data;
- },
- async delete(folder, file) {
- const response = await apiReq.delete(
- API_ROUTES.migrationsImportTypeFileNameDelete(folder, file),
- null,
- () => i18n.t("general.file-folder-not-found"),
- () => i18n.t("migration.migration-data-removed")
- );
- return response;
- },
- async import(folder, file) {
- let response = await apiReq.post(API_ROUTES.migrationsImportTypeFileNameImport(folder, file));
- store.dispatch("requestRecentRecipes");
- return response.data;
- },
-};
diff --git a/frontend.old/src/api/recipe.js b/frontend.old/src/api/recipe.js
deleted file mode 100644
index 6a4445c7fd31..000000000000
--- a/frontend.old/src/api/recipe.js
+++ /dev/null
@@ -1,181 +0,0 @@
-import { API_ROUTES } from "./apiRoutes";
-import { apiReq } from "./api-utils";
-import { store } from "../store";
-import i18n from "@/i18n.js";
-
-export const recipeAPI = {
- /**
- * Returns the Default Recipe Settings for the Site
- * @returns {AxoisResponse} Axois Response Object
- */
- async getDefaultSettings() {
- const response = await apiReq.get(API_ROUTES.aboutRecipesDefaults);
- return response;
- },
-
- /**
- * Create a Recipe by URL
- * @param {string} recipeURL
- * @returns {string} Recipe Slug
- */
- async createByURL(recipeURL) {
- const response = await apiReq.post(API_ROUTES.recipesCreateUrl, { url: recipeURL }, false, () =>
- i18n.t("recipe.recipe-created")
- );
-
- store.dispatch("requestRecentRecipes");
- return response;
- },
-
- async getAllByCategory(categories) {
- let response = await apiReq.post(API_ROUTES.recipesCategory, categories);
- return response.data;
- },
-
- async create(recipeData) {
- const response = await apiReq.post(
- API_ROUTES.recipesCreate,
- recipeData,
- () => i18n.t("recipe.recipe-creation-failed"),
- () => i18n.t("recipe.recipe-created")
- );
- store.dispatch("requestRecentRecipes");
- return response.data;
- },
-
- async requestDetails(recipeSlug) {
- const response = await apiReq.getSafe(API_ROUTES.recipesRecipeSlug(recipeSlug));
- return response;
- },
-
- updateImage(recipeSlug, fileObject, overrideSuccessMsg = false) {
- const formData = new FormData();
- formData.append("image", fileObject);
- formData.append("extension", fileObject.name.split(".").pop());
-
- let successMessage = null;
- if (!overrideSuccessMsg) {
- successMessage = function() {
- return overrideSuccessMsg ? null : i18n.t("recipe.recipe-image-updated");
- };
- }
-
- return apiReq.put(
- API_ROUTES.recipesRecipeSlugImage(recipeSlug),
- formData,
- () => i18n.t("general.image-upload-failed"),
- successMessage
- );
- },
-
- async createAsset(recipeSlug, fileObject, name, icon) {
- const fd = new FormData();
- fd.append("file", fileObject);
- fd.append("extension", fileObject.name.split(".").pop());
- fd.append("name", name);
- fd.append("icon", icon);
- const response = apiReq.post(API_ROUTES.recipesRecipeSlugAssets(recipeSlug), fd);
- return response;
- },
-
- updateImagebyURL(slug, url) {
- return apiReq.post(
- API_ROUTES.recipesRecipeSlugImage(slug),
- { url: url },
- () => i18n.t("general.image-upload-failed"),
- () => i18n.t("recipe.recipe-image-updated")
- );
- },
-
- async update(data) {
- let response = await apiReq.put(
- API_ROUTES.recipesRecipeSlug(data.slug),
- data,
- () => i18n.t("recipe.recipe-update-failed"),
- () => i18n.t("recipe.recipe-updated")
- );
- if (response) {
- store.dispatch("patchRecipe", response.data);
- return response.data.slug; // ! Temporary until I rewrite to refresh page without additional request
- }
- },
-
- async patch(data) {
- let response = await apiReq.patch(API_ROUTES.recipesRecipeSlug(data.slug), data);
- store.dispatch("patchRecipe", response.data);
- return response.data;
- },
-
- async delete(recipeSlug) {
- const response = await apiReq.delete(
- API_ROUTES.recipesRecipeSlug(recipeSlug),
- null,
- () => i18n.t("recipe.unable-to-delete-recipe"),
- () => i18n.t("recipe.recipe-deleted")
- );
- store.dispatch("dropRecipe", response.data);
- return response;
- },
-
- async allSummary(start = 0, limit = 9999) {
- const response = await apiReq.get(API_ROUTES.recipesSummary, {
- params: { start: start, limit: limit },
- });
- return response.data;
- },
-
- async allUntagged() {
- const response = await apiReq.get(API_ROUTES.recipesSummaryUntagged);
- return response.data;
- },
-
- async allUnategorized() {
- const response = await apiReq.get(API_ROUTES.recipesSummaryUncategorized);
- return response.data;
- },
-
- recipeImage(recipeSlug, version = null, key = null) {
- return `/api/media/recipes/${recipeSlug}/images/original.webp?&rnd=${key}&version=${version}`;
- },
-
- recipeSmallImage(recipeSlug, version = null, key = null) {
- return `/api/media/recipes/${recipeSlug}/images/min-original.webp?&rnd=${key}&version=${version}`;
- },
-
- recipeTinyImage(recipeSlug, version = null, key = null) {
- return `/api/media/recipes/${recipeSlug}/images/tiny-original.webp?&rnd=${key}&version=${version}`;
- },
-
- recipeAssetPath(recipeSlug, assetName) {
- return `/api/media/recipes/${recipeSlug}/assets/${assetName}`;
- },
-
- /** Create comment in the Database
- * @param slug
- */
- async createComment(slug, data) {
- const response = await apiReq.post(API_ROUTES.recipesSlugComments(slug), data);
- return response.data;
- },
- /** Update comment in the Database
- * @param slug
- * @param id
- */
- async updateComment(slug, id, data) {
- const response = await apiReq.put(API_ROUTES.recipesSlugCommentsId(slug, id), data);
- return response.data;
- },
- /** Delete comment from the Database
- * @param slug
- * @param id
- */
- async deleteComment(slug, id) {
- const response = await apiReq.delete(API_ROUTES.recipesSlugCommentsId(slug, id));
- return response.data;
- },
-
- async testScrapeURL(url) {
- const response = await apiReq.post(API_ROUTES.recipesTestScrapeUrl, { url: url });
- return response.data;
- },
-};
diff --git a/frontend.old/src/api/settings.js b/frontend.old/src/api/settings.js
deleted file mode 100644
index ffb2af344bbc..000000000000
--- a/frontend.old/src/api/settings.js
+++ /dev/null
@@ -1,19 +0,0 @@
-import { apiReq } from "./api-utils";
-import { API_ROUTES } from "./apiRoutes";
-
-export const settingsAPI = {
- async requestAll() {
- let response = await apiReq.get(API_ROUTES.siteSettings);
- return response.data;
- },
-
- async testWebhooks() {
- let response = await apiReq.post(API_ROUTES.siteSettingsWebhooksTest);
- return response.data;
- },
-
- async update(body) {
- let response = await apiReq.put(API_ROUTES.siteSettings, body);
- return response.data;
- },
-};
diff --git a/frontend.old/src/api/shoppingLists.js b/frontend.old/src/api/shoppingLists.js
deleted file mode 100644
index 74a7c9e2cd1c..000000000000
--- a/frontend.old/src/api/shoppingLists.js
+++ /dev/null
@@ -1,33 +0,0 @@
-// This Content is Auto Generated
-import { API_ROUTES } from "./apiRoutes";
-import { apiReq } from "./api-utils";
-
-export const shoppingListsAPI = {
- /** Create Shopping List in the Database
- */
- async createShoppingList(data) {
- const response = await apiReq.post(API_ROUTES.shoppingLists, data);
- return response.data;
- },
- /** Get Shopping List from the Database
- * @param id
- */
- async getShoppingList(id) {
- const response = await apiReq.get(API_ROUTES.shoppingListsId(id));
- return response.data;
- },
- /** Update Shopping List in the Database
- * @param id
- */
- async updateShoppingList(id, data) {
- const response = await apiReq.put(API_ROUTES.shoppingListsId(id), data);
- return response.data;
- },
- /** Delete Shopping List from the Database
- * @param id
- */
- async deleteShoppingList(id) {
- const response = await apiReq.delete(API_ROUTES.shoppingListsId(id));
- return response.data;
- },
-};
diff --git a/frontend.old/src/api/signUps.js b/frontend.old/src/api/signUps.js
deleted file mode 100644
index 946a8ea71063..000000000000
--- a/frontend.old/src/api/signUps.js
+++ /dev/null
@@ -1,35 +0,0 @@
-import { apiReq } from "./api-utils";
-import i18n from "@/i18n.js";
-import { API_ROUTES } from "./apiRoutes";
-
-export const signupAPI = {
- async getAll() {
- let response = await apiReq.get(API_ROUTES.usersSignUps);
- return response.data;
- },
- async createToken(data) {
- let response = await apiReq.post(
- API_ROUTES.usersSignUps,
- data,
- () => i18n.t("signup.sign-up-link-creation-failed"),
- () => i18n.t("signup.sign-up-link-created")
- );
- return response.data;
- },
- async deleteToken(token) {
- return await apiReq.delete(
- API_ROUTES.usersSignUpsToken(token),
- null,
- () => i18n.t("signup.sign-up-token-deletion-failed"),
- () => i18n.t("signup.sign-up-token-deleted")
- );
- },
- async createUser(token, data) {
- return apiReq.post(
- API_ROUTES.usersSignUpsToken(token),
- data,
- () => i18n.t("user.you-are-not-allowed-to-create-a-user"),
- () => i18n.t("user.user-created")
- );
- },
-};
diff --git a/frontend.old/src/api/siteSettings.js b/frontend.old/src/api/siteSettings.js
deleted file mode 100644
index 0d25479df24c..000000000000
--- a/frontend.old/src/api/siteSettings.js
+++ /dev/null
@@ -1,71 +0,0 @@
-import { apiReq } from "./api-utils";
-import { store } from "@/store";
-import i18n from "@/i18n.js";
-import { API_ROUTES } from "./apiRoutes";
-
-export const siteSettingsAPI = {
- async get() {
- let response = await apiReq.get(API_ROUTES.siteSettings);
- return response.data;
- },
-
- async update(body) {
- const response = await apiReq.put(
- API_ROUTES.siteSettings,
- body,
- () => i18n.t("settings.settings-update-failed"),
- () => i18n.t("settings.settings-updated")
- );
- if (response) {
- store.dispatch("requestSiteSettings");
- }
- return response;
- },
-
- async getPages() {
- let response = await apiReq.get(API_ROUTES.siteSettingsCustomPages);
- return response.data;
- },
-
- async getPage(id) {
- let response = await apiReq.get(API_ROUTES.siteSettingsCustomPagesId(id));
- return response.data;
- },
-
- createPage(body) {
- return apiReq.post(
- API_ROUTES.siteSettingsCustomPages,
- body,
- () => i18n.t("page.page-creation-failed"),
- () => i18n.t("page.new-page-created")
- );
- },
-
- async deletePage(id) {
- return await apiReq.delete(
- API_ROUTES.siteSettingsCustomPagesId(id),
- null,
- () => i18n.t("page.page-deletion-failed"),
- () => i18n.t("page.page-deleted")
- );
- },
-
- updatePage(body) {
- return apiReq.put(
- API_ROUTES.siteSettingsCustomPagesId(body.id),
- body,
- () => i18n.t("page.page-update-failed"),
- () => i18n.t("page.page-updated")
- );
- },
-
- async updateAllPages(allPages) {
- let response = await apiReq.put(
- API_ROUTES.siteSettingsCustomPages,
- allPages,
- () => i18n.t("page.pages-update-failed"),
- () => i18n.t("page.pages-updated")
- );
- return response;
- },
-};
diff --git a/frontend.old/src/api/themes.js b/frontend.old/src/api/themes.js
deleted file mode 100644
index ba19e0083c64..000000000000
--- a/frontend.old/src/api/themes.js
+++ /dev/null
@@ -1,42 +0,0 @@
-import { apiReq } from "./api-utils";
-import i18n from "@/i18n.js";
-import { API_ROUTES } from "./apiRoutes";
-
-export const themeAPI = {
- async requestAll() {
- let response = await apiReq.get(API_ROUTES.themes);
- return response.data;
- },
-
- async requestByName(name) {
- let response = await apiReq.get(API_ROUTES.themesId(name));
- return response.data;
- },
-
- async create(postBody) {
- return await apiReq.post(
- API_ROUTES.themesCreate,
- postBody,
- () => i18n.t("settings.theme.error-creating-theme-see-log-file"),
- () => i18n.t("settings.theme.theme-saved")
- );
- },
-
- update(data) {
- return apiReq.put(
- API_ROUTES.themesId(data.id),
- data,
- () => i18n.t("settings.theme.error-updating-theme"),
- () => i18n.t("settings.theme.theme-updated")
- );
- },
-
- delete(id) {
- return apiReq.delete(
- API_ROUTES.themesId(id),
- null,
- () => i18n.t("settings.theme.error-deleting-theme"),
- () => i18n.t("settings.theme.theme-deleted")
- );
- },
-};
diff --git a/frontend.old/src/api/upload.js b/frontend.old/src/api/upload.js
deleted file mode 100644
index efd9ada3e1fc..000000000000
--- a/frontend.old/src/api/upload.js
+++ /dev/null
@@ -1,14 +0,0 @@
-import { apiReq } from "./api-utils";
-import i18n from "@/i18n.js";
-
-export const utilsAPI = {
- // import { api } from "@/api";
- uploadFile(url, fileObject) {
- return apiReq.post(
- url,
- fileObject,
- () => i18n.t("general.failure-uploading-file"),
- () => i18n.t("general.file-uploaded")
- );
- },
-};
diff --git a/frontend.old/src/api/users.js b/frontend.old/src/api/users.js
deleted file mode 100644
index d354a6e6614b..000000000000
--- a/frontend.old/src/api/users.js
+++ /dev/null
@@ -1,107 +0,0 @@
-import { API_ROUTES } from "./apiRoutes";
-import { apiReq } from "./api-utils";
-import i18n from "@/i18n.js";
-
-export const userAPI = {
- async login(formData) {
- let response = await apiReq.post(API_ROUTES.authToken, formData, null, () => {
- return i18n.t("user.user-successfully-logged-in");
- });
- return response;
- },
- async refresh() {
- return apiReq.getSafe(API_ROUTES.authRefresh);
- },
- async allUsers() {
- let response = await apiReq.get(API_ROUTES.users);
- return response.data;
- },
- create(user) {
- return apiReq.post(
- API_ROUTES.users,
- user,
- () => i18n.t("user.user-creation-failed"),
- () => i18n.t("user.user-created")
- );
- },
- async self() {
- return apiReq.getSafe(API_ROUTES.usersSelf);
- },
- async byID(id) {
- let response = await apiReq.get(API_ROUTES.usersId(id));
- return response.data;
- },
- update(user) {
- return apiReq.put(
- API_ROUTES.usersId(user.id),
- user,
- () => i18n.t("user.user-update-failed"),
- () => i18n.t("user.user-updated")
- );
- },
- changePassword(id, password) {
- return apiReq.put(
- API_ROUTES.usersIdPassword(id),
- password,
- () => i18n.t("user.existing-password-does-not-match"),
- () => i18n.t("user.password-updated")
- );
- },
-
- delete(id) {
- return apiReq.delete(API_ROUTES.usersId(id), null, deleteErrorText, () => {
- return i18n.t("user.user-deleted");
- });
- },
- resetPassword(id) {
- return apiReq.put(
- API_ROUTES.usersIdResetPassword(id),
- null,
- () => i18n.t("user.password-reset-failed"),
- () => i18n.t("user.password-has-been-reset-to-the-default-password")
- );
- },
- async createAPIToken(name) {
- const response = await apiReq.post(API_ROUTES.usersApiTokens, { name });
- return response.data;
- },
- async deleteAPIToken(id) {
- const response = await apiReq.delete(API_ROUTES.usersApiTokensTokenId(id));
- return response.data;
- },
- /** Adds a Recipe to the users favorites
- * @param id
- */
- async getFavorites(id) {
- const response = await apiReq.get(API_ROUTES.usersIdFavorites(id));
- return response.data;
- },
- /** Adds a Recipe to the users favorites
- * @param id
- */
- async addFavorite(id, slug) {
- const response = await apiReq.post(API_ROUTES.usersIdFavoritesSlug(id, slug));
- return response.data;
- },
- /** Adds a Recipe to the users favorites
- * @param id
- */
- async removeFavorite(id, slug) {
- const response = await apiReq.delete(API_ROUTES.usersIdFavoritesSlug(id, slug));
- return response.data;
- },
-
- userProfileImage(id) {
- if (!id || id === undefined) return;
- return `/api/users/${id}/image`;
- },
-};
-
-const deleteErrorText = response => {
- switch (response.data.detail) {
- case "SUPER_USER":
- return i18n.t("user.error-cannot-delete-super-user");
- default:
- return i18n.t("user.you-are-not-allowed-to-delete-this-user");
- }
-};
diff --git a/frontend.old/src/components/Fallbacks/NoRecipe.vue b/frontend.old/src/components/Fallbacks/NoRecipe.vue
deleted file mode 100644
index d196b487c05b..000000000000
--- a/frontend.old/src/components/Fallbacks/NoRecipe.vue
+++ /dev/null
@@ -1,17 +0,0 @@
-
-
-
- {{ $t('general.no-recipe-found') }}
-
-
-
-
-
-
-
-
diff --git a/frontend.old/src/components/Fallbacks/The404.vue b/frontend.old/src/components/Fallbacks/The404.vue
deleted file mode 100644
index 60f8d5ba19cd..000000000000
--- a/frontend.old/src/components/Fallbacks/The404.vue
+++ /dev/null
@@ -1,51 +0,0 @@
-
-
-
-
- {{ $t('page.404-page-not-found') }}
-
-
-
-
-
4
-
- {{ $globals.icons.primary }}
-
-
4
-
-
-
-
-
-
- {{ button.icon }}
- {{ button.text }}
-
-
-
-
-
-
-
-
-
-
\ No newline at end of file
diff --git a/frontend.old/src/components/FormHelpers/CategoryTagSelector.vue b/frontend.old/src/components/FormHelpers/CategoryTagSelector.vue
deleted file mode 100644
index e02b988b48ef..000000000000
--- a/frontend.old/src/components/FormHelpers/CategoryTagSelector.vue
+++ /dev/null
@@ -1,134 +0,0 @@
-
-
-
-
- {{ data.item.name || data.item }}
-
-
-
-
-
-
-
-
-
-
-
diff --git a/frontend.old/src/components/FormHelpers/ColorPickerDialog.vue b/frontend.old/src/components/FormHelpers/ColorPickerDialog.vue
deleted file mode 100644
index 13ba003ec499..000000000000
--- a/frontend.old/src/components/FormHelpers/ColorPickerDialog.vue
+++ /dev/null
@@ -1,65 +0,0 @@
-
-
-
-
{{ buttonText }}
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
diff --git a/frontend.old/src/components/FormHelpers/DatePicker.vue b/frontend.old/src/components/FormHelpers/DatePicker.vue
deleted file mode 100644
index 610ec00a8970..000000000000
--- a/frontend.old/src/components/FormHelpers/DatePicker.vue
+++ /dev/null
@@ -1,27 +0,0 @@
-
-
-
-
-
-
-
diff --git a/frontend.old/src/components/FormHelpers/ImportOptions.vue b/frontend.old/src/components/FormHelpers/ImportOptions.vue
deleted file mode 100644
index 519037a46e53..000000000000
--- a/frontend.old/src/components/FormHelpers/ImportOptions.vue
+++ /dev/null
@@ -1,69 +0,0 @@
-
-
-
-
-
-
-
\ No newline at end of file
diff --git a/frontend.old/src/components/FormHelpers/LanguageSelector.vue b/frontend.old/src/components/FormHelpers/LanguageSelector.vue
deleted file mode 100644
index c480fad998d5..000000000000
--- a/frontend.old/src/components/FormHelpers/LanguageSelector.vue
+++ /dev/null
@@ -1,48 +0,0 @@
-
-
-
-
-
-
diff --git a/frontend.old/src/components/FormHelpers/TimePickerDialog.vue b/frontend.old/src/components/FormHelpers/TimePickerDialog.vue
deleted file mode 100644
index 8a7c9e851a22..000000000000
--- a/frontend.old/src/components/FormHelpers/TimePickerDialog.vue
+++ /dev/null
@@ -1,42 +0,0 @@
-
-
-
-
-
-
-
- {{ $t("general.cancel") }}
- {{ $t("general.ok") }}
-
-
-
-
-
-
-
diff --git a/frontend.old/src/components/ImportSummaryDialog/DataTable.vue b/frontend.old/src/components/ImportSummaryDialog/DataTable.vue
deleted file mode 100644
index 8391bc95eedf..000000000000
--- a/frontend.old/src/components/ImportSummaryDialog/DataTable.vue
+++ /dev/null
@@ -1,46 +0,0 @@
-
-
-
-
-
- {{ item.status ? "Imported" : "Failed" }}
-
-
-
-
-
-
- {{ item.exception }}
-
- |
-
-
-
-
-
-
-
-
diff --git a/frontend.old/src/components/ImportSummaryDialog/index.vue b/frontend.old/src/components/ImportSummaryDialog/index.vue
deleted file mode 100644
index d754451fd0f7..000000000000
--- a/frontend.old/src/components/ImportSummaryDialog/index.vue
+++ /dev/null
@@ -1,142 +0,0 @@
-
-
-
-
-
-
- {{ $globals.icons.import }}
-
-
- {{ $t("settings.backup.import-summary") }}
-
-
-
-
-
-
-
-
-
{{ values.title }}
-
- {{ $t("general.success-count", { count: values.success }) }}
- {{ $t("general.failed-count", { count: values.failure }) }}
-
-
-
-
-
- {{ $t("general.recipes") }}
- {{ $t("general.themes") }}
- {{ $t("general.settings") }}
- {{ $t("settings.pages") }}
- {{ $t("user.users") }}
- {{ $t("group.groups") }}
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
diff --git a/frontend.old/src/components/Login/LoginDialog.vue b/frontend.old/src/components/Login/LoginDialog.vue
deleted file mode 100644
index fae060b1d075..000000000000
--- a/frontend.old/src/components/Login/LoginDialog.vue
+++ /dev/null
@@ -1,28 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
diff --git a/frontend.old/src/components/Login/LoginForm.vue b/frontend.old/src/components/Login/LoginForm.vue
deleted file mode 100644
index d3bda238cce9..000000000000
--- a/frontend.old/src/components/Login/LoginForm.vue
+++ /dev/null
@@ -1,94 +0,0 @@
-
-
-
-
-
- {{ $globals.icons.user }}
-
-
- {{ $t("user.login") }}
-
-
-
-
-
-
-
-
- {{ $t("user.sign-in") }}
-
-
-
- {{ $t("user.could-not-validate-credentials") }}
-
-
-
-
-
-
-
-
-
diff --git a/frontend.old/src/components/Login/SignUpForm.vue b/frontend.old/src/components/Login/SignUpForm.vue
deleted file mode 100644
index 4aa118f8f30a..000000000000
--- a/frontend.old/src/components/Login/SignUpForm.vue
+++ /dev/null
@@ -1,141 +0,0 @@
-
-
-
-
-
- {{ $globals.icons.user }}
-
-
-
- {{ $t("signup.sign-up") }}
-
-
-
-
- {{ $t("signup.welcome-to-mealie") }}
-
-
-
-
-
-
-
-
-
- {{ $t("signup.sign-up") }}
-
-
-
- {{ $t("signup.error-signing-up") }}
-
-
-
-
-
-
-
-
-
diff --git a/frontend.old/src/components/MealPlan/ShoppingListDialog.vue b/frontend.old/src/components/MealPlan/ShoppingListDialog.vue
deleted file mode 100644
index d66d27219a89..000000000000
--- a/frontend.old/src/components/MealPlan/ShoppingListDialog.vue
+++ /dev/null
@@ -1,100 +0,0 @@
-
-
-
-
-
- {{ $t("shopping-list.shopping-list") }}
-
-
- {{ $t("meal-plan.group") }}
-
-
-
-
-
-
- {{ recipe.name }}
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
diff --git a/frontend.old/src/components/UI/Buttons/TheButton.vue b/frontend.old/src/components/UI/Buttons/TheButton.vue
deleted file mode 100644
index a3973429b90d..000000000000
--- a/frontend.old/src/components/UI/Buttons/TheButton.vue
+++ /dev/null
@@ -1,163 +0,0 @@
-
-
-
-
- {{ btnAttrs.icon }}
-
-
-
- {{ btnAttrs.text }}
-
-
-
-
-
-
-
\ No newline at end of file
diff --git a/frontend.old/src/components/UI/Buttons/TheCopyButton.vue b/frontend.old/src/components/UI/Buttons/TheCopyButton.vue
deleted file mode 100644
index adfa5a11ddd2..000000000000
--- a/frontend.old/src/components/UI/Buttons/TheCopyButton.vue
+++ /dev/null
@@ -1,71 +0,0 @@
-
-
-
-
- {{ $globals.icons.contentCopy }}
-
-
-
-
- {{ $globals.icons.clipboardCheck }}
-
- {{ $t("general.copied") }}!
-
-
-
-
-
-
-
\ No newline at end of file
diff --git a/frontend.old/src/components/UI/Buttons/TheDownloadBtn.vue b/frontend.old/src/components/UI/Buttons/TheDownloadBtn.vue
deleted file mode 100644
index 02e7a21a30e8..000000000000
--- a/frontend.old/src/components/UI/Buttons/TheDownloadBtn.vue
+++ /dev/null
@@ -1,54 +0,0 @@
-
-
-
-
- {{ showButtonText }}
-
-
-
-
-
-
-
-
diff --git a/frontend.old/src/components/UI/Buttons/TheUploadBtn.vue b/frontend.old/src/components/UI/Buttons/TheUploadBtn.vue
deleted file mode 100644
index 95b4a8ce5262..000000000000
--- a/frontend.old/src/components/UI/Buttons/TheUploadBtn.vue
+++ /dev/null
@@ -1,89 +0,0 @@
-
-
-
-
-
- {{ effIcon }}
- {{ text ? text : defaultText }}
-
-
-
-
-
-
-
-
diff --git a/frontend.old/src/components/UI/Dialogs/BackupDialog.vue b/frontend.old/src/components/UI/Dialogs/BackupDialog.vue
deleted file mode 100644
index d9edb45efc53..000000000000
--- a/frontend.old/src/components/UI/Dialogs/BackupDialog.vue
+++ /dev/null
@@ -1,146 +0,0 @@
-
-
-
-
-
- {{ $globals.icons.create }} {{ $t("general.custom") }}
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- {{ $t("general.options") }}
-
-
-
- {{ $t("general.templates") }}
-
-
-
-
-
-
-
-
-
-
-
diff --git a/frontend.old/src/components/UI/Dialogs/ImportDialog.vue b/frontend.old/src/components/UI/Dialogs/ImportDialog.vue
deleted file mode 100644
index af7002f4cd3b..000000000000
--- a/frontend.old/src/components/UI/Dialogs/ImportDialog.vue
+++ /dev/null
@@ -1,119 +0,0 @@
-
-
-
- {{ $d(new Date(date), "medium") }}
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- {{ $globals.icons.download }}
- {{ $t("general.download") }}
-
-
-
-
-
-
-
-
-
-
-
diff --git a/frontend.old/src/components/UI/Dialogs/SearchDialog.vue b/frontend.old/src/components/UI/Dialogs/SearchDialog.vue
deleted file mode 100644
index c45dbf9ae276..000000000000
--- a/frontend.old/src/components/UI/Dialogs/SearchDialog.vue
+++ /dev/null
@@ -1,172 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
- {{ $globals.icons.close }}
-
-
-
-
-
-
- {{ $t("search.results") }}
-
- {{ $t("search.advanced-search") }}
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
\ No newline at end of file
diff --git a/frontend.old/src/components/UI/GlobalSnackbar.vue b/frontend.old/src/components/UI/GlobalSnackbar.vue
deleted file mode 100644
index 39b9cfab127c..000000000000
--- a/frontend.old/src/components/UI/GlobalSnackbar.vue
+++ /dev/null
@@ -1,46 +0,0 @@
-
-
-
-
- {{ icon }}
-
-
- {{ snackbar.title }}
- {{ snackbar.text }}
-
-
-
- {{ $t("general.close") }}
-
-
-
-
-
-
-
\ No newline at end of file
diff --git a/frontend.old/src/components/UI/LogCard.vue b/frontend.old/src/components/UI/LogCard.vue
deleted file mode 100644
index 9fbc9a906cda..000000000000
--- a/frontend.old/src/components/UI/LogCard.vue
+++ /dev/null
@@ -1,81 +0,0 @@
-
-
-
-
- Log
-
-
-
-
-
-
- {{ $globals.icons.download }}
-
-
-
-
-
-
-
- {{ item }}
-
-
-
-
-
-
-
-
-
\ No newline at end of file
diff --git a/frontend.old/src/components/UI/Search/FuseSearchBar.vue b/frontend.old/src/components/UI/Search/FuseSearchBar.vue
deleted file mode 100644
index fa109197e945..000000000000
--- a/frontend.old/src/components/UI/Search/FuseSearchBar.vue
+++ /dev/null
@@ -1,80 +0,0 @@
-
-
-
-
-
-
-
-
-
diff --git a/frontend.old/src/components/UI/Search/SearchBar.vue b/frontend.old/src/components/UI/Search/SearchBar.vue
deleted file mode 100644
index bf2b145aec01..000000000000
--- a/frontend.old/src/components/UI/Search/SearchBar.vue
+++ /dev/null
@@ -1,65 +0,0 @@
-
-
-
-
-
-
- {{ $globals.icons.search }}
-
-
-
-
-
-
-
-
-
diff --git a/frontend.old/src/components/UI/Search/SearchDialog.vue b/frontend.old/src/components/UI/Search/SearchDialog.vue
deleted file mode 100644
index ea4a6f1918f8..000000000000
--- a/frontend.old/src/components/UI/Search/SearchDialog.vue
+++ /dev/null
@@ -1,103 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
- {{ $globals.icons.close }}
-
-
-
-
-
-
-
-
-
diff --git a/frontend.old/src/components/UI/StatCard.vue b/frontend.old/src/components/UI/StatCard.vue
deleted file mode 100644
index a9f11c9451f3..000000000000
--- a/frontend.old/src/components/UI/StatCard.vue
+++ /dev/null
@@ -1,103 +0,0 @@
-w
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
diff --git a/frontend.old/src/components/UI/TheAppBar.vue b/frontend.old/src/components/UI/TheAppBar.vue
deleted file mode 100644
index e54393d7301d..000000000000
--- a/frontend.old/src/components/UI/TheAppBar.vue
+++ /dev/null
@@ -1,102 +0,0 @@
-
-
-
-
-
- {{ $globals.icons.menu }}
-
-
-
- {{ $globals.icons.primary }}
-
-
-
-
-
- Mealie
-
-
-
-
-
-
-
-
-
-
- {{ isDark ? $t("settings.theme.switch-to-light-mode") : $t("settings.theme.switch-to-dark-mode") }}
-
-
-
-
-
-
- {{ $globals.icons.search }}
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
diff --git a/frontend.old/src/components/UI/TheRecipeFab.vue b/frontend.old/src/components/UI/TheRecipeFab.vue
deleted file mode 100644
index 8136527ff534..000000000000
--- a/frontend.old/src/components/UI/TheRecipeFab.vue
+++ /dev/null
@@ -1,247 +0,0 @@
-
-
-
-
-
- {{ $globals.icons.link }}
-
-
-
- {{ $t("new-recipe.from-url") }}
-
-
-
-
-
-
-
-
-
-
-
- {{ $globals.icons.robot }}
- {{ $t("new-recipe.error-title") }}
-
-
-
-
- {{ $t("new-recipe.error-details") }}
-
-
-
-
- {{ $globals.icons.externalLink }}
- {{ $t("new-recipe.view-scraped-data") }}
-
-
-
-
-
-
-
-
-
-
- {{ $globals.icons.close }}
- {{ $t("general.close") }}
-
-
-
- {{ $globals.icons.create }}
- {{ $t("general.submit") }}
-
-
-
-
-
-
-
- {{ $t("new-recipe.upload-individual-zip-file") }}
-
-
- {{ this.fileName }}
-
-
-
-
-
-
-
-
-
-
- {{ $globals.icons.createAlt }}
-
-
-
-
-
- {{ $globals.icons.link }}
-
-
- {{ $t("new-recipe.from-url") }}
-
-
-
-
- {{ $globals.icons.edit }}
-
-
- {{ $t("general.new") }}
-
-
-
-
- {{ $globals.icons.zip }}
-
-
- {{ $t("general.upload") }}
-
-
-
-
-
-
-
-
diff --git a/frontend.old/src/components/UI/TheSidebar.vue b/frontend.old/src/components/UI/TheSidebar.vue
deleted file mode 100644
index 5d64acde2db6..000000000000
--- a/frontend.old/src/components/UI/TheSidebar.vue
+++ /dev/null
@@ -1,253 +0,0 @@
-
-
-
-
-
-
-
-
- {{ $globals.icons.heart }}
-
-
- {{ $t("general.favorites") }}
-
-
-
-
-
-
-
-
- {{ nav.icon }}
-
- {{ nav.title }}
-
-
-
-
-
-
-
- {{ $globals.icons.heart }}
-
- {{ $t("about.support") }}
-
-
-
- {{ $globals.icons.information }}
-
-
-
- {{ $t("settings.current") }}
- {{ appVersion }}
-
-
-
- {{ $t("settings.latest") }}
- {{ latestVersion }}
-
-
-
-
-
-
-
-
-
-
-
-
diff --git a/frontend.old/src/components/UI/TheSiteMenu.vue b/frontend.old/src/components/UI/TheSiteMenu.vue
deleted file mode 100644
index b9de04a1086b..000000000000
--- a/frontend.old/src/components/UI/TheSiteMenu.vue
+++ /dev/null
@@ -1,109 +0,0 @@
-
-
-
-
-
-
- {{ $globals.icons.user }}
-
-
-
-
-
-
- {{ item.icon }}
-
-
-
- {{ item.title }}
-
-
-
-
-
-
-
-
-
-
diff --git a/frontend.old/src/i18n.js b/frontend.old/src/i18n.js
deleted file mode 100644
index 7433c36a8b24..000000000000
--- a/frontend.old/src/i18n.js
+++ /dev/null
@@ -1,38 +0,0 @@
-import Vue from "vue";
-import VueI18n from "vue-i18n";
-import Vuetify from "@/plugins/vuetify";
-import axios from 'axios';
-
-Vue.use(VueI18n);
-
-const i18n = new VueI18n();
-
-export default i18n;
-
-const loadedLanguages = [];
-
-function setI18nLanguage (lang) {
- i18n.locale = lang;
- Vuetify.framework.lang.current = lang;
- axios.defaults.headers.common['Accept-Language'] = lang
- document.querySelector('html').setAttribute('lang', lang)
- return lang
-}
-
-export function loadLanguageAsync(lang) {
-
- if ( ! loadedLanguages.includes(lang)) {
- const messages = import(`./locales/messages/${lang}.json`);
- const dateTimeFormats = import(`./locales/dateTimeFormats/${lang}.json`);
-
- return Promise.all([messages, dateTimeFormats]).then(
- values => {
- i18n.setLocaleMessage(lang, values[0].default)
- i18n.setDateTimeFormat(lang, values[1].default)
- loadedLanguages.push(lang)
- return setI18nLanguage(lang)
- }
- )
- }
- return Promise.resolve(setI18nLanguage(lang))
-}
\ No newline at end of file
diff --git a/frontend.old/src/installCompAPI.js b/frontend.old/src/installCompAPI.js
deleted file mode 100644
index c1a45139dba5..000000000000
--- a/frontend.old/src/installCompAPI.js
+++ /dev/null
@@ -1,3 +0,0 @@
-import Vue from "vue";
-import VueCompositionAPI from "@vue/composition-api";
-Vue.use(VueCompositionAPI);
diff --git a/frontend.old/src/main.js b/frontend.old/src/main.js
deleted file mode 100644
index d7ad28f64372..000000000000
--- a/frontend.old/src/main.js
+++ /dev/null
@@ -1,44 +0,0 @@
-import "./installCompAPI"; // Must Be First
-
-import Vue from "vue";
-import App from "./App.vue";
-import vuetify from "./plugins/vuetify";
-import store from "./store";
-import VueRouter from "vue-router";
-import { router } from "./routes";
-import { globals } from "@/utils/globals";
-import i18n from "./i18n";
-import "typeface-roboto/index.css";
-import "./registerServiceWorker";
-
-Vue.config.productionTip = false;
-Vue.use(VueRouter);
-Vue.component("TheButton", () => import("@/components/UI/Buttons/TheButton.vue"));
-
-Vue.prototype.$globals = globals;
-
-const vueApp = new Vue({
- vuetify,
- store,
- router,
- i18n,
- render: h => h(App),
-}).$mount("#app");
-
-// Truncate
-const truncate = function(text, length, clamp) {
- clamp = clamp || "...";
- let node = document.createElement("div");
- node.innerHTML = text;
- let content = node.textContent;
- return content.length > length ? content.slice(0, length) + clamp : content;
-};
-
-const titleCase = function(value) {
- return value.replace(/(?:^|\s|-)\S/g, x => x.toUpperCase());
-};
-
-Vue.filter("truncate", truncate);
-Vue.filter("titleCase", titleCase);
-
-export { router, vueApp };
diff --git a/frontend.old/src/mixins/initials.js b/frontend.old/src/mixins/initials.js
deleted file mode 100644
index 60448d1be521..000000000000
--- a/frontend.old/src/mixins/initials.js
+++ /dev/null
@@ -1,18 +0,0 @@
-export const initials = {
- computed: {
- initials() {
- if (!this.user.fullName) return "00"
- const allNames = this.user.fullName.trim().split(" ");
- const initials = allNames.reduce(
- (acc, curr, index) => {
- if (index === 0 || index === allNames.length - 1) {
- acc = `${acc}${curr.charAt(0).toUpperCase()}`;
- }
- return acc;
- },
- [""]
- );
- return initials;
- },
- },
-};
diff --git a/frontend.old/src/mixins/user.js b/frontend.old/src/mixins/user.js
deleted file mode 100644
index 2d500bea42d9..000000000000
--- a/frontend.old/src/mixins/user.js
+++ /dev/null
@@ -1,24 +0,0 @@
-import { store } from "@/store";
-export const user = {
- computed: {
- user() {
- return store.getters.getUserData;
- },
- loggedIn() {
- return store.getters.getIsLoggedIn;
- },
- initials() {
- const allNames = this.user.fullName.trim().split(" ");
- const initials = allNames.reduce(
- (acc, curr, index) => {
- if (index === 0 || index === allNames.length - 1) {
- acc = `${acc}${curr.charAt(0).toUpperCase()}`;
- }
- return acc;
- },
- [""]
- );
- return initials;
- },
- },
-};
diff --git a/frontend.old/src/mixins/utilMixins.js b/frontend.old/src/mixins/utilMixins.js
deleted file mode 100644
index 2b9bf8504264..000000000000
--- a/frontend.old/src/mixins/utilMixins.js
+++ /dev/null
@@ -1,7 +0,0 @@
-export const utilMixins = {
- commputed: {
- isMobile() {
- return this.$vuetify.breakpoint.name === "xs";
- },
- },
-};
diff --git a/frontend.old/src/mixins/validators.js b/frontend.old/src/mixins/validators.js
deleted file mode 100644
index ba795b3effc8..000000000000
--- a/frontend.old/src/mixins/validators.js
+++ /dev/null
@@ -1,15 +0,0 @@
-const EMAIL_REGEX = /^(([^<>()[\]\\.,;:\s@"]+(\.[^<>()[\]\\.,;:\s@"]+)*)|(".+"))@(([[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}])|(([a-zA-Z\-0-9]+\.)+[a-zA-Z]{2,}))$/;
-
-export const validators = {
- data() {
- return {
- emailRule: v => !v || EMAIL_REGEX.test(v) || this.$t("user.e-mail-must-be-valid"),
-
- existsRule: value => !!value || this.$t("general.field-required"),
-
- minRule: v => v.length >= 8 || this.$t("user.use-8-characters-or-more-for-your-password"),
-
- whiteSpace: v => !v || v.split(" ").length <= 1 || this.$t("recipe.no-white-space-allowed"),
- };
- },
-};
diff --git a/frontend.old/src/pages/404Page.vue b/frontend.old/src/pages/404Page.vue
deleted file mode 100644
index e98fab51ceee..000000000000
--- a/frontend.old/src/pages/404Page.vue
+++ /dev/null
@@ -1,13 +0,0 @@
-
-
-
-
-
-
-
-
diff --git a/frontend.old/src/pages/Admin/About/index.vue b/frontend.old/src/pages/Admin/About/index.vue
deleted file mode 100644
index fae2ee76d1db..000000000000
--- a/frontend.old/src/pages/Admin/About/index.vue
+++ /dev/null
@@ -1,130 +0,0 @@
-
-
-
-
-
-
- {{ $globals.icons.heart }}
-
- {{ $t("about.support") }}
-
-
-
- {{ $globals.icons.github }}
-
- {{ $t("about.github") }}
-
-
-
- {{ $globals.icons.account }}
-
- {{ $t("about.portfolio") }}
-
-
-
- {{ $globals.icons.folderOutline }}
-
- {{ $t("about.docs") }}
-
-
-
-
-
- {{ $t("about.about-mealie") }}
-
-
-
-
-
-
- {{ property.icon || $globals.icons.user }}
-
-
-
- {{ property.name }}
- {{ property.value }}
-
-
-
-
-
-
-
-
-
-
- {{ $globals.icons.codeBraces }} {{ $t("about.download-recipe-json") }}
-
-
-
-
-
-
-
-
-
-
-
diff --git a/frontend.old/src/pages/Admin/Dashboard/BackupViewer.vue b/frontend.old/src/pages/Admin/Dashboard/BackupViewer.vue
deleted file mode 100644
index e65d29622457..000000000000
--- a/frontend.old/src/pages/Admin/Dashboard/BackupViewer.vue
+++ /dev/null
@@ -1,162 +0,0 @@
-
-
-
-
-
-
-
-
-
- {{ $t("settings.backup-and-exports") }}
-
-
-
- {{ total }}
-
-
-
-
-
-
-
- {{ $globals.icons.upload }} {{ $t("general.upload") }}
-
-
-
-
-
-
- {{ $globals.icons.create }} {{ $t("general.create") }}
-
-
-
-
-
-
-
-
- {{ $globals.icons.database }}
-
-
-
-
-
-
-
- {{ $d(Date.parse(item.date), "medium") }}
-
-
-
-
-
- {{ $globals.icons.delete }}
-
-
-
-
-
-
-
-
-
-
-
-
-
\ No newline at end of file
diff --git a/frontend.old/src/pages/Admin/Dashboard/EventViewer.vue b/frontend.old/src/pages/Admin/Dashboard/EventViewer.vue
deleted file mode 100644
index 5dcd44ec397b..000000000000
--- a/frontend.old/src/pages/Admin/Dashboard/EventViewer.vue
+++ /dev/null
@@ -1,135 +0,0 @@
-
-
-
-
-
-
-
- {{ $t("settings.events") }}
-
-
-
- {{ total }}
-
-
-
-
-
- {{ $globals.icons.notificationClearAll }} {{ $t("general.clear") }}
-
-
-
-
-
-
-
-
- {{ icons[item.category].icon }}
-
-
-
-
-
-
-
-
- {{ $d(Date.parse(item.timeStamp), "long") }}
-
-
-
-
-
- {{ $globals.icons.delete }}
-
-
-
-
-
-
-
-
-
-
-
-
-
\ No newline at end of file
diff --git a/frontend.old/src/pages/Admin/Dashboard/index.vue b/frontend.old/src/pages/Admin/Dashboard/index.vue
deleted file mode 100644
index f217e700551c..000000000000
--- a/frontend.old/src/pages/Admin/Dashboard/index.vue
+++ /dev/null
@@ -1,126 +0,0 @@
-
-
-
-
-
-
-
-
- {{ $t("general.recipes") }}
-
-
-
- {{ statistics.totalRecipes }}
-
-
-
-
-
-
- {{ $globals.icons.tags }}
- {{ $tc("tag.untagged-count", [statistics.untaggedRecipes]) }}
-
-
- {{ $globals.icons.tags }}
- {{ $tc("category.uncategorized-count", [statistics.uncategorizedRecipes]) }}
-
-
-
-
-
-
-
-
-
-
- {{ $t("user.users") }}
-
-
- {{ statistics.totalUsers }}
-
-
-
-
-
-
- {{ $globals.icons.user }}
- {{ $t("user.manage-users") }}
-
-
-
-
-
-
-
-
-
-
- {{ $t("group.groups") }}
-
-
-
- {{ statistics.totalGroups }}
-
-
-
-
-
-
- {{ $globals.icons.group }}
- {{ $t("group.manage-groups") }}
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
\ No newline at end of file
diff --git a/frontend.old/src/pages/Admin/ManageUsers/GroupCard.vue b/frontend.old/src/pages/Admin/ManageUsers/GroupCard.vue
deleted file mode 100644
index 3ab26d3f2860..000000000000
--- a/frontend.old/src/pages/Admin/ManageUsers/GroupCard.vue
+++ /dev/null
@@ -1,122 +0,0 @@
-
-
-
-
-
- {{ group.name }}
-
- {{ $t("group.group-id-with-value", { groupID: group.id }) }}
-
-
-
- {{ property.icon || $globals.icons.user }}
-
-
-
- {{ property.text }}
- {{ property.value }}
-
-
-
-
-
-
-
-
- {{ $t("general.delete") }}
-
-
-
- {{ $t("general.edit") }}
-
-
-
-
-
-
-
-
-
diff --git a/frontend.old/src/pages/Admin/ManageUsers/GroupDashboard.vue b/frontend.old/src/pages/Admin/ManageUsers/GroupDashboard.vue
deleted file mode 100644
index 1b83f80100b1..000000000000
--- a/frontend.old/src/pages/Admin/ManageUsers/GroupDashboard.vue
+++ /dev/null
@@ -1,100 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
- {{ $t("group.create-group") }}
-
-
-
-
-
- {{ $globals.icons.group }}
-
-
-
- {{ $t("group.create-group") }}
-
-
-
-
-
-
-
-
-
-
-
-
- {{ $t("general.cancel") }}
-
-
- {{ $t("general.create") }}
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
diff --git a/frontend.old/src/pages/Admin/ManageUsers/TheSignUpTable.vue b/frontend.old/src/pages/Admin/ManageUsers/TheSignUpTable.vue
deleted file mode 100644
index 95a442535eb4..000000000000
--- a/frontend.old/src/pages/Admin/ManageUsers/TheSignUpTable.vue
+++ /dev/null
@@ -1,230 +0,0 @@
-
-
-
-
-
- {{ $globals.icons.externalLink }}
-
-
- {{ $t("signup.sign-up-links") }}
-
-
-
-
-
-
- {{ $t("user.create-link") }}
-
-
-
-
-
- {{ $globals.icons.user }}
-
-
-
- {{ $t("user.create-link") }}
-
-
-
-
-
-
-
-
-
-
-
-
-
- {{ $t("general.cancel") }}
-
-
- {{ $t("general.save") }}
-
-
-
-
-
-
-
-
-
-
-
- {{ `${baseURL}/sign-up/${item.token}` }}
-
-
-
-
-
- {{ $globals.icons.admin }}
-
- {{ item.admin ? $t("general.yes") : $t("general.no") }}
-
-
-
-
-
- {{ $globals.icons.delete }}
-
- {{ $t("general.delete") }}
-
-
-
-
-
-
-
-
-
-
diff --git a/frontend.old/src/pages/Admin/ManageUsers/TheUserTable.vue b/frontend.old/src/pages/Admin/ManageUsers/TheUserTable.vue
deleted file mode 100644
index 45f0350057ed..000000000000
--- a/frontend.old/src/pages/Admin/ManageUsers/TheUserTable.vue
+++ /dev/null
@@ -1,284 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
- {{ $t("user.create-user") }}
-
-
-
-
-
- {{ $globals.icons.user }}
-
-
-
- {{ formTitle }}
-
-
-
-
- {{ $t("user.user-id-with-value", { id: editedItem.id }) }}
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- {{ $t("user.reset-password") }}
-
-
-
- {{ $t("general.cancel") }}
-
-
- {{ $t("general.save") }}
-
-
-
-
-
-
-
-
-
-
-
-
- {{ $globals.icons.delete }}
-
- {{ $t("general.delete") }}
-
-
-
- {{ $globals.icons.edit }}
-
- {{ $t("general.edit") }}
-
-
-
- {{ item.admin ? "Admin" : "User" }}
-
-
-
- {{ $t("general.reset") }}
-
-
-
-
-
-
-
-
-
-
diff --git a/frontend.old/src/pages/Admin/ManageUsers/index.vue b/frontend.old/src/pages/Admin/ManageUsers/index.vue
deleted file mode 100644
index 15e1888877ef..000000000000
--- a/frontend.old/src/pages/Admin/ManageUsers/index.vue
+++ /dev/null
@@ -1,68 +0,0 @@
-
-
-
-
-
-
-
- {{ $t("user.users") }}
- {{ $globals.icons.user }}
-
-
-
- {{ $t("signup.sign-up-links") }}
- {{ $globals.icons.accountPlusOutline }}
-
-
-
- {{ $t("group.groups") }}
- {{ $globals.icons.group }}
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
diff --git a/frontend.old/src/pages/Admin/Migration/MigrationCard.vue b/frontend.old/src/pages/Admin/Migration/MigrationCard.vue
deleted file mode 100644
index 54492f0486eb..000000000000
--- a/frontend.old/src/pages/Admin/Migration/MigrationCard.vue
+++ /dev/null
@@ -1,94 +0,0 @@
-
-
-
-
- {{ title }}
-
-
-
-
-
- {{ description }}
-
-
-
-
-
- {{ $globals.icons.import }}
-
-
-
- {{ migration.name }}
-
-
- {{ $d(new Date(migration.date), "medium") }}
-
-
-
-
-
-
-
- {{ $t("general.delete") }}
-
-
- {{ $t("general.import") }}
-
-
-
-
-
-
-
- {{ $t("migration.no-migration-data-available") }}
-
-
-
-
-
-
-
-
-
-
diff --git a/frontend.old/src/pages/Admin/Migration/MigrationDialog.vue b/frontend.old/src/pages/Admin/Migration/MigrationDialog.vue
deleted file mode 100644
index 5b5b3ab7bf54..000000000000
--- a/frontend.old/src/pages/Admin/Migration/MigrationDialog.vue
+++ /dev/null
@@ -1,106 +0,0 @@
-
-
-
-
-
-
- {{ $globals.icons.import }}
-
-
- Migration Summary
-
-
-
-
-
-
-
-
-
{{ values.title }}
-
- Success: {{ values.success }}
- Failed: {{ values.failure }}
-
-
-
-
-
- {{ $t("general.recipes") }}
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
diff --git a/frontend.old/src/pages/Admin/Migration/index.vue b/frontend.old/src/pages/Admin/Migration/index.vue
deleted file mode 100644
index c345bde2996f..000000000000
--- a/frontend.old/src/pages/Admin/Migration/index.vue
+++ /dev/null
@@ -1,82 +0,0 @@
-
-
-
-
- {{ $t("migration.recipe-migration") }}
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
diff --git a/frontend.old/src/pages/Admin/Profile/APITokenCard.vue b/frontend.old/src/pages/Admin/Profile/APITokenCard.vue
deleted file mode 100644
index 6977229a5fc7..000000000000
--- a/frontend.old/src/pages/Admin/Profile/APITokenCard.vue
+++ /dev/null
@@ -1,150 +0,0 @@
-
-
-
-
-
- {{ $t("settings.token.api-tokens") }}
-
-
- {{ user.tokens.length }}
-
-
-
-
- {{ $t("settings.token.active-tokens") }}
-
-
-
-
-
-
- {{ $globals.icons.api }}
-
-
-
-
-
-
-
-
-
- {{ $globals.icons.delete }}
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- {{
- $t(
- "settings.token.copy-this-token-for-use-with-an-external-application-this-token-will-not-be-viewable-again"
- )
- }}
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
diff --git a/frontend.old/src/pages/Admin/Profile/ProfileGroupCard.vue b/frontend.old/src/pages/Admin/Profile/ProfileGroupCard.vue
deleted file mode 100644
index 27c4f5fb8187..000000000000
--- a/frontend.old/src/pages/Admin/Profile/ProfileGroupCard.vue
+++ /dev/null
@@ -1,211 +0,0 @@
-
-
-
-
-
-
-
- {{ currentGroup.name }}
-
-
-
-
-
- {{ $t("meal-plan.dinner-tonight") }}
-
-
-
- {{ $t("user.users-header") }}
-
-
-
-
-
-
-
- {{ generateInitials(item.fullName) }}
-
-
-
-
-
- {{ item.fullName }}
-
-
-
-
-
-
-
-
-
-
- {{ $globals.icons.food }}
-
- {{ $t("meal-plan.mealplan-settings") }}
-
-
-
-
- {{ $t("meal-plan.mealplan-categories") }}
-
- {{ $t("meal-plan.only-recipes-with-these-categories-will-be-used-in-meal-plans") }}
-
-
-
-
- {{ $t("settings.webhooks.webhooks-caps") }}
-
- {{
- $t(
- "settings.webhooks.the-urls-listed-below-will-recieve-webhooks-containing-the-recipe-data-for-the-meal-plan-on-its-scheduled-day-currently-webhooks-will-execute-at"
- )
- }}
- {{ groupSettings.webhookTime }}
-
-
-
-
-
-
-
-
-
-
-
- {{ $globals.icons.webhook }}
- {{ $t("general.new") }}
-
-
-
-
-
-
-
- {{ $globals.icons.webhook }}
- {{ $t("settings.webhooks.test-webhooks") }}
-
-
-
-
-
-
-
-
-
-
-
diff --git a/frontend.old/src/pages/Admin/Profile/ProfileThemeCard.vue b/frontend.old/src/pages/Admin/Profile/ProfileThemeCard.vue
deleted file mode 100644
index 6a2559eead38..000000000000
--- a/frontend.old/src/pages/Admin/Profile/ProfileThemeCard.vue
+++ /dev/null
@@ -1,225 +0,0 @@
-
-
-
-
-
-
-
-
- {{ selectedTheme.name }}
-
-
-
-
-
-
-
- {{ $globals.icons.desktopTowerMonitor }}
-
- {{ $t("settings.theme.default-to-system") }}
-
-
-
-
- {{ $globals.icons.weatherSunny }}
-
- {{ $t("settings.theme.light") }}
-
-
-
-
- {{ $globals.icons.weatherNight }}
-
- {{ $t("settings.theme.dark") }}
-
-
-
-
-
-
-
-
-
-
-
-
- {{ $globals.icons.formatColorFill }}
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- {{ $globals.icons.edit }}
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
\ No newline at end of file
diff --git a/frontend.old/src/pages/Admin/Profile/UserCard.vue b/frontend.old/src/pages/Admin/Profile/UserCard.vue
deleted file mode 100644
index 11519ce55d35..000000000000
--- a/frontend.old/src/pages/Admin/Profile/UserCard.vue
+++ /dev/null
@@ -1,198 +0,0 @@
-
-
-
-
-
-
- {{ initials }}
-
-
-
-
-
-
-
-
- {{ $t("group.group-with-value", { groupID: user.group }) }}
-
-
-
-
-
-
-
- {{ $globals.icons.lock }}
- {{ $t("settings.change-password") }}
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
diff --git a/frontend.old/src/pages/Admin/Profile/index.vue b/frontend.old/src/pages/Admin/Profile/index.vue
deleted file mode 100644
index e6cfa1a38301..000000000000
--- a/frontend.old/src/pages/Admin/Profile/index.vue
+++ /dev/null
@@ -1,35 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
diff --git a/frontend.old/src/pages/Admin/Settings/CreatePageDialog.vue b/frontend.old/src/pages/Admin/Settings/CreatePageDialog.vue
deleted file mode 100644
index 355e5a060bce..000000000000
--- a/frontend.old/src/pages/Admin/Settings/CreatePageDialog.vue
+++ /dev/null
@@ -1,98 +0,0 @@
-
-
-
-
-
- {{ $globals.icons.pageLayoutBody }}
-
-
-
- {{ title }}
-
-
-
-
-
-
-
-
-
-
-
-
-
- {{ $t("general.cancel") }}
-
-
- {{ buttonText }}
-
-
-
-
-
-
-
-
-
-
diff --git a/frontend.old/src/pages/Admin/Settings/CustomPageCreator.vue b/frontend.old/src/pages/Admin/Settings/CustomPageCreator.vue
deleted file mode 100644
index 2da1ce91f97e..000000000000
--- a/frontend.old/src/pages/Admin/Settings/CustomPageCreator.vue
+++ /dev/null
@@ -1,126 +0,0 @@
-
-
-
-
-
- {{ $t("settings.custom-pages") }}
-
-
-
-
-
-
-
-
- {{ item.name }}
-
-
-
-
-
- {{ cat.name }}
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
diff --git a/frontend.old/src/pages/Admin/Settings/HomePageSettings.vue b/frontend.old/src/pages/Admin/Settings/HomePageSettings.vue
deleted file mode 100644
index 14c0c8ec8966..000000000000
--- a/frontend.old/src/pages/Admin/Settings/HomePageSettings.vue
+++ /dev/null
@@ -1,220 +0,0 @@
-
-
-
- {{ $t("settings.homepage.home-page") }}
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- {{ $globals.icons.home }}
-
-
-
- {{ $t("settings.homepage.home-page-sections") }}
-
-
-
-
-
-
-
-
-
- {{ $globals.icons.menu }}
-
-
-
-
-
-
- {{ $globals.icons.delete }}
-
-
-
-
-
-
-
-
-
-
-
- {{ $globals.icons.tags }}
-
-
-
- {{ $t("settings.homepage.all-categories") }}
-
-
-
-
-
-
-
-
-
-
- {{ $globals.icons.menu }}
-
-
-
-
-
-
- {{ $globals.icons.delete }}
-
-
-
-
-
-
-
-
-
-
- {{ $t("settings.locale-settings") }}
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
diff --git a/frontend.old/src/pages/Admin/Settings/index.vue b/frontend.old/src/pages/Admin/Settings/index.vue
deleted file mode 100644
index c94954efcdbd..000000000000
--- a/frontend.old/src/pages/Admin/Settings/index.vue
+++ /dev/null
@@ -1,34 +0,0 @@
-
-
-
- {{ $t("settings.admin-settings") }}
-
-
-
- {{ $t("settings.local-api") }}
- {{ $globals.icons.openInNew }}
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
diff --git a/frontend.old/src/pages/Admin/ToolBox/CategoryTagEditor/BulkAssign.vue b/frontend.old/src/pages/Admin/ToolBox/CategoryTagEditor/BulkAssign.vue
deleted file mode 100644
index 19c0aec4cfec..000000000000
--- a/frontend.old/src/pages/Admin/ToolBox/CategoryTagEditor/BulkAssign.vue
+++ /dev/null
@@ -1,149 +0,0 @@
-
-
-
-
-
-
-
-
-
-
- {{ $t("general.cancel") }}
-
-
-
- {{ $t("settings.toolbox.assign-all") }}
-
-
-
-
-
-
-
-
-
- {{ $t("settings.toolbox.bulk-assign") }}
-
-
-
-
-
-
-
diff --git a/frontend.old/src/pages/Admin/ToolBox/CategoryTagEditor/RemoveUnused.vue b/frontend.old/src/pages/Admin/ToolBox/CategoryTagEditor/RemoveUnused.vue
deleted file mode 100644
index c5df2b71a451..000000000000
--- a/frontend.old/src/pages/Admin/ToolBox/CategoryTagEditor/RemoveUnused.vue
+++ /dev/null
@@ -1,89 +0,0 @@
-
-
-
-
-
-
- {{ item.name }}
-
-
-
-
- {{ $t("settings.toolbox.no-unused-items") }}
-
-
-
- {{ $t("general.cancel") }}
-
-
-
- {{ $t("general.delete") }}
-
-
-
-
-
- {{ $t("settings.toolbox.remove-unused") }}
-
-
-
-
-
-
-
diff --git a/frontend.old/src/pages/Admin/ToolBox/CategoryTagEditor/index.vue b/frontend.old/src/pages/Admin/ToolBox/CategoryTagEditor/index.vue
deleted file mode 100644
index d3fe0715b182..000000000000
--- a/frontend.old/src/pages/Admin/ToolBox/CategoryTagEditor/index.vue
+++ /dev/null
@@ -1,237 +0,0 @@
-
-
-
-
-
-
-
-
-
-
- {{ $tc("settings.toolbox.recipes-affected", renameTarget.recipes.length || 0) }}
-
-
-
-
-
-
-
-
- {{ $t("general.create") }}
-
-
-
-
-
-
- {{ $t("settings.toolbox.title-case-all") }}
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- {{ item.name }}
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
diff --git a/frontend.old/src/pages/Admin/ToolBox/EventNotification.vue b/frontend.old/src/pages/Admin/ToolBox/EventNotification.vue
deleted file mode 100644
index c022dbb3c1e5..000000000000
--- a/frontend.old/src/pages/Admin/ToolBox/EventNotification.vue
+++ /dev/null
@@ -1,213 +0,0 @@
-
-
-
-
-
-
-
- {{ $t("events.notification") }}
-
-
-
- {{ $t("events.new-notification-form-description") }}
-
-
-
-
-
-
-
-
-
-
-
- {{ $globals.icons.testTube }}
- {{ $t("general.test") }}
-
-
- {{ $t("events.subscribed-events") }}
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- {{ getIcon(item.type).icon }}
-
-
- {{ item[boolHeader.value] }}
-
-
- {{ item[boolHeader.value] ? $globals.icons.check : $globals.icons.close }}
-
-
-
-
-
- {{ $globals.icons.testTube }}
-
- {{ $t("general.test") }}
-
-
-
- {{ item[boolHeader.value] }}
-
-
-
-
-
-
-
-
-
-
-
diff --git a/frontend.old/src/pages/Admin/ToolBox/RecipeOrganizer.vue b/frontend.old/src/pages/Admin/ToolBox/RecipeOrganizer.vue
deleted file mode 100644
index 9e08cfb536be..000000000000
--- a/frontend.old/src/pages/Admin/ToolBox/RecipeOrganizer.vue
+++ /dev/null
@@ -1,91 +0,0 @@
-
-
-
-
-
- {{ $globals.icons.tags }}-multiple
- {{ $t("recipe.categories") }}
-
-
-
- {{ $globals.icons.tags }}-multiple
- {{ $t("tag.tags") }}
-
-
-
-
-
-
-
-
-
-
-
-
-
\ No newline at end of file
diff --git a/frontend.old/src/pages/Admin/ToolBox/index.vue b/frontend.old/src/pages/Admin/ToolBox/index.vue
deleted file mode 100644
index c80cce98db44..000000000000
--- a/frontend.old/src/pages/Admin/ToolBox/index.vue
+++ /dev/null
@@ -1,62 +0,0 @@
-
-
-
-
-
-
-
- {{ $t("settings.notify") }}
- {{ $globals.icons.bellAlert }}
-
-
- {{ $t("recipe.categories") }}
- {{ $globals.icons.tags }}
-
-
-
- {{ $t("tag.tags") }}
- {{ $globals.icons.tags }}
-
-
- {{ $t("settings.organize") }}
- {{ $globals.icons.broom }}
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
diff --git a/frontend.old/src/pages/Admin/index.vue b/frontend.old/src/pages/Admin/index.vue
deleted file mode 100644
index 55456e5b9030..000000000000
--- a/frontend.old/src/pages/Admin/index.vue
+++ /dev/null
@@ -1,13 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
diff --git a/frontend.old/src/pages/Debug.vue b/frontend.old/src/pages/Debug.vue
deleted file mode 100644
index d4b8db4ee2a2..000000000000
--- a/frontend.old/src/pages/Debug.vue
+++ /dev/null
@@ -1,19 +0,0 @@
-
-
-
-
-
-
-
-
-
-
diff --git a/frontend.old/src/pages/HomePage.vue b/frontend.old/src/pages/HomePage.vue
deleted file mode 100644
index 74b8449e824d..000000000000
--- a/frontend.old/src/pages/HomePage.vue
+++ /dev/null
@@ -1,75 +0,0 @@
-
-
-
-
-
-
-
-
-
-
diff --git a/frontend.old/src/pages/LoginPage.vue b/frontend.old/src/pages/LoginPage.vue
deleted file mode 100644
index 996b40b5235c..000000000000
--- a/frontend.old/src/pages/LoginPage.vue
+++ /dev/null
@@ -1,40 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
diff --git a/frontend.old/src/pages/MealPlan/Planner.vue b/frontend.old/src/pages/MealPlan/Planner.vue
deleted file mode 100644
index 15c1dc59c0b7..000000000000
--- a/frontend.old/src/pages/MealPlan/Planner.vue
+++ /dev/null
@@ -1,150 +0,0 @@
-
-
-
-
-
-
-
- {{ $t("meal-plan.meal-plans") }}
-
-
-
-
-
-
-
- {{ $d(new Date(mealplan.startDate.replaceAll("-", "/")), "short") }} -
- {{ $d(new Date(mealplan.endDate.replaceAll("-", "/")), "short") }}
-
-
-
-
-
- {{ $globals.icons.cartCheck }}
-
- {{ $t("shopping-list.create-shopping-list") }}
-
-
-
- {{ $globals.icons.mdiCartCheck }}
-
- {{ $t("shopping-list.shopping-list") }}
-
-
-
- {{ $t("general.link-copied") }}
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
diff --git a/frontend.old/src/pages/MealPlan/ThisWeek.vue b/frontend.old/src/pages/MealPlan/ThisWeek.vue
deleted file mode 100644
index 002d4da30654..000000000000
--- a/frontend.old/src/pages/MealPlan/ThisWeek.vue
+++ /dev/null
@@ -1,75 +0,0 @@
-
-
-
-
- {{ $d(new Date(planDay.date), "short") }}
-
-
-
-
- {{ $t('meal-plan.main') }}
-
-
-
- {{ $t('meal-plan.sides') }}
-
-
-
-
-
-
-
-
-
-
diff --git a/frontend.old/src/pages/Recipe/NewRecipe.vue b/frontend.old/src/pages/Recipe/NewRecipe.vue
deleted file mode 100644
index 6e100865d900..000000000000
--- a/frontend.old/src/pages/Recipe/NewRecipe.vue
+++ /dev/null
@@ -1,126 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
diff --git a/frontend.old/src/pages/Recipe/ScraperDebugger.vue b/frontend.old/src/pages/Recipe/ScraperDebugger.vue
deleted file mode 100644
index 8b91bfb85b0c..000000000000
--- a/frontend.old/src/pages/Recipe/ScraperDebugger.vue
+++ /dev/null
@@ -1,61 +0,0 @@
-
-
-
-
-
- {{ $globals.icons.testTube }}
- Test Scrape
-
-
-
-
-
-
-
diff --git a/frontend.old/src/pages/Recipe/ViewRecipe.vue b/frontend.old/src/pages/Recipe/ViewRecipe.vue
deleted file mode 100644
index 3cc353258b9d..000000000000
--- a/frontend.old/src/pages/Recipe/ViewRecipe.vue
+++ /dev/null
@@ -1,271 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
diff --git a/frontend.old/src/pages/Recipes/AllRecipes.vue b/frontend.old/src/pages/Recipes/AllRecipes.vue
deleted file mode 100644
index da1069b18d02..000000000000
--- a/frontend.old/src/pages/Recipes/AllRecipes.vue
+++ /dev/null
@@ -1,58 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
diff --git a/frontend.old/src/pages/Recipes/CategoryTagPage.vue b/frontend.old/src/pages/Recipes/CategoryTagPage.vue
deleted file mode 100644
index eff8a13ddfd6..000000000000
--- a/frontend.old/src/pages/Recipes/CategoryTagPage.vue
+++ /dev/null
@@ -1,108 +0,0 @@
-
-
-
-
-
- {{ $globals.icons.tags }}
-
- {{ altTitle }}
-
-
-
-
-
-
-
-
- {{ $globals.icons.tags }}
-
- {{ item.name }}
-
-
-
-
-
-
-
-
-
-
-
-
-
-
diff --git a/frontend.old/src/pages/Recipes/CustomPage.vue b/frontend.old/src/pages/Recipes/CustomPage.vue
deleted file mode 100644
index c9b91b70e5ab..000000000000
--- a/frontend.old/src/pages/Recipes/CustomPage.vue
+++ /dev/null
@@ -1,75 +0,0 @@
-
-
-
- {{ $globals.icons.pages }}
- {{ page.name }}
-
-
-
-
-
- {{ item.name }}
-
-
-
-
-
-
-
-
-
-
-
-
-
diff --git a/frontend.old/src/pages/Recipes/Favorites.vue b/frontend.old/src/pages/Recipes/Favorites.vue
deleted file mode 100644
index 950210eff97f..000000000000
--- a/frontend.old/src/pages/Recipes/Favorites.vue
+++ /dev/null
@@ -1,49 +0,0 @@
-
-
-
-
-
-
-
-
-
-
diff --git a/frontend.old/src/pages/SearchPage/FilterSelector.vue b/frontend.old/src/pages/SearchPage/FilterSelector.vue
deleted file mode 100644
index 43ed22f47b33..000000000000
--- a/frontend.old/src/pages/SearchPage/FilterSelector.vue
+++ /dev/null
@@ -1,52 +0,0 @@
-
-
-
-
- {{ $t("search.include") }}
-
-
-
- {{ $t("search.exclude") }}
-
-
-
-
-
- {{ $t("search.and") }}
-
-
- {{ $t("search.or") }}
-
-
-
-
-
-
-
-
diff --git a/frontend.old/src/pages/SearchPage/index.vue b/frontend.old/src/pages/SearchPage/index.vue
deleted file mode 100644
index 8d8ffdaa6e4b..000000000000
--- a/frontend.old/src/pages/SearchPage/index.vue
+++ /dev/null
@@ -1,168 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- {{ $t("category.category-filter") }}
-
-
-
-
-
-
- {{ $t("search.tag-filter") }}
-
-
-
-
-
-
-
-
-
-
-
-
-
diff --git a/frontend.old/src/pages/ShoppingList/index.vue b/frontend.old/src/pages/ShoppingList/index.vue
deleted file mode 100644
index 051c9eb54c53..000000000000
--- a/frontend.old/src/pages/ShoppingList/index.vue
+++ /dev/null
@@ -1,281 +0,0 @@
-
-
-
-
-
- {{ $globals.icons.arrowLeftBold }}
-
- {{ $t("shopping-list.all-lists") }}
-
-
- {{ $globals.icons.formatListChecks }}
-
- {{ $t("shopping-list.shopping-lists") }}
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- {{ item.name }}
-
-
-
-
-
-
-
- {{ $globals.icons.cartCheck }}
-
- {{ $t("general.view") }}
-
-
-
-
-
-
-
-
-
-
-
- {{ activeList.name }}
-
-
-
-
-
-
-
-
-
-
-
- {{ $t("shopping-list.quantity", [item.quantity]) }}
-
-
-
- {{ $globals.icons.mdiMinus }}
-
-
-
-
- {{ $globals.icons.create }}
-
-
-
-
-
- {{ $globals.icons.delete }}
-
-
-
-
-
-
- {{ item.quantity }}
-
-
- {{ $globals.icons.windowClose }}
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- {{ $globals.icons.primary }}
-
- {{ $t("shopping-list.from-recipe") }}
-
-
-
- {{ $globals.icons.create }}
-
- {{ $t("general.new") }}
-
-
-
-
-
-
-
-
-
-
\ No newline at end of file
diff --git a/frontend.old/src/pages/SignUpPage.vue b/frontend.old/src/pages/SignUpPage.vue
deleted file mode 100644
index d1e79154f9df..000000000000
--- a/frontend.old/src/pages/SignUpPage.vue
+++ /dev/null
@@ -1,40 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
diff --git a/frontend.old/src/plugins/vuetify.js b/frontend.old/src/plugins/vuetify.js
deleted file mode 100644
index 6f54f8ad73ee..000000000000
--- a/frontend.old/src/plugins/vuetify.js
+++ /dev/null
@@ -1,63 +0,0 @@
-import Vue from "vue";
-import Vuetify from "vuetify/lib";
-
-Vue.use(Vuetify);
-
-import de from "vuetify/es5/locale/de";
-import en from "vuetify/es5/locale/en";
-import es from "vuetify/es5/locale/es";
-import fr from "vuetify/es5/locale/fr";
-import it from "vuetify/es5/locale/it";
-import nl from "vuetify/es5/locale/nl";
-import pl from "vuetify/es5/locale/pl";
-import sv from "vuetify/es5/locale/sv";
-import zhHans from "vuetify/es5/locale/zh-Hans";
-
-const vuetify = new Vuetify({
- theme: {
- dark: false,
- options: { customProperties: true },
-
- themes: {
- light: {
- primary: "#E58325",
- accent: "#00457A",
- secondary: "#973542",
- success: "#43A047",
- info: "#FFFD99",
- warning: "#FF4081",
- error: "#EF5350",
- },
- dark: {
- primary: "#4527A0",
- accent: "#FF4081",
- secondary: "#26C6DA",
- success: "#43A047",
- info: "#2196F3",
- warning: "#FB8C00",
- error: "#FF5252",
- },
- },
- },
- lang: {
- locales: {
- "de-DE": de,
- "en-US": en,
- "en-GB": en,
- "es-ES": es,
- "fr-FR": fr,
- "it-IT": it,
- "nl-NL": nl,
- "pl-PL": pl,
- "sv-SE": sv,
- "zh-CN": zhHans,
- },
- current: "en-US",
- },
- icons: {
- iconfont: "mdiSvg",
- },
-});
-
-export default vuetify;
-export { vuetify };
diff --git a/frontend.old/src/registerServiceWorker.js b/frontend.old/src/registerServiceWorker.js
deleted file mode 100644
index 6cb38651365d..000000000000
--- a/frontend.old/src/registerServiceWorker.js
+++ /dev/null
@@ -1,39 +0,0 @@
-/* eslint-disable no-console */
-
-import { register } from "register-service-worker";
-
-if (process.env.NODE_ENV === "production") {
- register(`${process.env.BASE_URL}service-worker.js`, {
- ready() {
- console.log("Service worker is active.");
- },
- registered(registration) {
- console.log("Service worker has been registered.");
-
- // Routinely check for app updates by testing for a new service worker.
- setInterval(() => {
- registration.update();
- }, 1000 * 60 * 60); // hourly checks
- },
- cached() {
- console.log("Content has been cached for offline use.");
- },
- updatefound() {
- console.log("New content is downloading.");
- },
- updated(registration) {
- console.log("New content is available; please refresh.");
-
- // Add a custom event and dispatch it.
- // Used to display of a 'refresh' banner following a service worker update.
- // Set the event payload to the service worker registration object.
- document.dispatchEvent(new CustomEvent("swUpdated", { detail: registration }));
- },
- offline() {
- console.log("No internet connection found. App is running in offline mode.");
- },
- error(error) {
- console.error("Error during service worker registration:", error);
- },
- });
-}
diff --git a/frontend.old/src/routes/admin.js b/frontend.old/src/routes/admin.js
deleted file mode 100644
index 4f580245d0ed..000000000000
--- a/frontend.old/src/routes/admin.js
+++ /dev/null
@@ -1,74 +0,0 @@
-const Admin = () => import(/* webpackChunkName: "admin-pages" */ "@/pages/Admin");
-const Migration = () => import(/* webpackChunkName: "admin-pages" */ "@/pages/Admin/Migration");
-const Profile = () => import(/* webpackChunkName: "admin-pages" */ "@/pages/Admin/Profile");
-const ManageUsers = () => import(/* webpackChunkName: "admin-pages" */ "@/pages/Admin/ManageUsers");
-const Settings = () => import(/* webpackChunkName: "admin-pages" */ "@/pages/Admin/Settings");
-const About = () => import(/* webpackChunkName: "admin-pages" */ "@/pages/Admin/About");
-const ToolBox = () => import(/* webpackChunkName: "admin-pages" */ "@/pages/Admin/ToolBox");
-const Dashboard = () => import(/* webpackChunkName: "admin-pages" */ "@/pages/Admin/Dashboard");
-import { store } from "../store";
-
-export const adminRoutes = {
- path: "/admin",
- component: Admin,
- beforeEnter: (to, _from, next) => {
- if (store.getters.getIsLoggedIn) {
- next();
- } else next({ path: "/login", query: { redirect: to.fullPath } });
- },
- children: [
- {
- path: "",
- component: Profile,
- },
- {
- path: "profile",
- component: Profile,
- meta: {
- title: "settings.profile",
- },
- },
- {
- path: "migrations",
- component: Migration,
- meta: {
- title: "settings.migrations",
- },
- },
- {
- path: "manage-users",
- component: ManageUsers,
- meta: {
- title: "user.manage-users",
- },
- },
- {
- path: "settings",
- component: Settings,
- meta: {
- title: "settings.site-settings",
- },
- },
- {
- path: "toolbox",
- component: ToolBox,
- meta: {
- title: "settings.toolbox.toolbox",
- },
- },
- {
- path: "about",
- component: About,
- meta: {
- title: "about.about",
- },
- },
- {
- path: "dashboard",
- component: Dashboard,
- meta: {
- title: "general.dashboard",
- },
- },
- ],
-};
diff --git a/frontend.old/src/routes/auth.js b/frontend.old/src/routes/auth.js
deleted file mode 100644
index 742472dd31a5..000000000000
--- a/frontend.old/src/routes/auth.js
+++ /dev/null
@@ -1,18 +0,0 @@
-const LoginPage = () => import("@/pages/LoginPage");
-const SignUpPage = () => import("@/pages/SignUpPage");
-import { store } from "../store";
-
-export const authRoutes = [
- {
- path: "/logout",
- beforeEnter: (_to, _from, next) => {
- store.commit("setToken", "");
- store.commit("setIsLoggedIn", false);
- next("/");
- },
- },
- { path: "/login", component: LoginPage },
-
- { path: "/sign-up", redirect: "/" },
- { path: "/sign-up/:token", component: SignUpPage },
-];
diff --git a/frontend.old/src/routes/general.js b/frontend.old/src/routes/general.js
deleted file mode 100644
index f7802fa94718..000000000000
--- a/frontend.old/src/routes/general.js
+++ /dev/null
@@ -1,16 +0,0 @@
-const SearchPage = () => import("@/pages/SearchPage");
-const ShoppingList = () => import("@/pages/ShoppingList");
-import HomePage from "@/pages/HomePage";
-
-export const generalRoutes = [
- { path: "/", name: "home", component: HomePage },
- { path: "/mealie", component: HomePage },
- { path: "/shopping-list", component: ShoppingList },
- {
- path: "/search",
- component: SearchPage,
- meta: {
- title: "search.search",
- },
- },
-];
diff --git a/frontend.old/src/routes/index.js b/frontend.old/src/routes/index.js
deleted file mode 100644
index 9ac473e420b3..000000000000
--- a/frontend.old/src/routes/index.js
+++ /dev/null
@@ -1,51 +0,0 @@
-import Page404 from "@/pages/404Page";
-import { adminRoutes } from "./admin";
-import { authRoutes } from "./auth";
-import { recipeRoutes } from "./recipes";
-import { mealRoutes } from "./meal";
-import { generalRoutes } from "./general";
-import { store } from "@/store";
-import VueRouter from "vue-router";
-import { loadLanguageAsync } from "@/i18n";
-import Vue from "vue";
-import i18n from "@/i18n.js";
-
-export const routes = [
- ...generalRoutes,
- adminRoutes,
- ...authRoutes,
- ...mealRoutes,
- ...recipeRoutes,
-
- { path: "/page-not-found", component: Page404 },
- { path: "*", component: Page404 },
-];
-
-const router = new VueRouter({
- base: process.env.BASE_URL,
- routes,
- mode: process.env.NODE_ENV === "production" ? "history" : "hash",
- scrollBehavior() {
- return { x: 0, y: 0 };
- },
-});
-
-const DEFAULT_TITLE = "Mealie";
-const TITLE_SEPARATOR = "|";
-const TITLE_SUFFIX = " " + TITLE_SEPARATOR + " " + DEFAULT_TITLE;
-router.afterEach(to => {
- Vue.nextTick(async () => {
- if (typeof to.meta.title === "function") {
- const title = await to.meta.title(to);
- document.title = title + TITLE_SUFFIX;
- } else {
- document.title = i18n.t(to.meta.title) ? i18n.t(to.meta.title) + TITLE_SUFFIX : DEFAULT_TITLE;
- }
- });
-});
-
-router.beforeEach((__, _, next) => {
- loadLanguageAsync(store.getters.getActiveLang).then(() => next());
-});
-
-export { router };
diff --git a/frontend.old/src/routes/meal.js b/frontend.old/src/routes/meal.js
deleted file mode 100644
index 4aca00dd883e..000000000000
--- a/frontend.old/src/routes/meal.js
+++ /dev/null
@@ -1,51 +0,0 @@
-const Planner = () => import("@/pages/MealPlan/Planner");
-const ThisWeek = () => import("@/pages/MealPlan/ThisWeek");
-import { api } from "@/api";
-import { utils } from "@/utils";
-import i18n from "@/i18n.js";
-
-export const mealRoutes = [
- {
- path: "/meal-plan",
- component: ThisWeek,
- meta: {
- title: "meal-plan.dinner-this-week",
- },
- },
- {
- path: "/meal-plan/planner",
- component: Planner,
- meta: {
- title: "meal-plan.meal-planner",
- },
- },
- {
- path: "/meal-plan/this-week",
- component: ThisWeek,
- meta: {
- title: "meal-plan.dinner-this-week",
- },
- },
- {
- path: "/meal-plan/today",
- beforeEnter: async (_to, _from, next) => {
- await todaysMealRoute().then(redirect => {
- if (redirect) {
- next(redirect);
- } else {
- utils.notify.error(i18n.t("meal-plan.no-meal-planned-for-today"));
- next(_from);
- }
- });
- },
- },
-];
-
-async function todaysMealRoute() {
- const response = await api.mealPlans.today();
- if (response.status == 200 && response.data) {
- return "/recipe/" + response.data.slug;
- } else {
- return null;
- }
-}
diff --git a/frontend.old/src/routes/recipes.js b/frontend.old/src/routes/recipes.js
deleted file mode 100644
index e2e3967aac2a..000000000000
--- a/frontend.old/src/routes/recipes.js
+++ /dev/null
@@ -1,37 +0,0 @@
-const ViewRecipe = () => import(/* webpackChunkName: "recipe-page" */ "@/pages/Recipe/ViewRecipe");
-const NewRecipe = () => import(/* webpackChunkName: "recipe-page" */ "@/pages/Recipe/NewRecipe");
-const ScraperDebugger = () => import("@/pages/Recipe/ScraperDebugger");
-const CustomPage = () => import("@/pages/Recipes/CustomPage");
-const AllRecipes = () => import("@/pages/Recipes/AllRecipes");
-const CategoryTagPage = () => import("@/pages/Recipes/CategoryTagPage");
-const Favorites = () => import("@/pages/Recipes/Favorites");
-import { api } from "@/api";
-
-export const recipeRoutes = [
- // Recipes
- { path: "/recipes/all", component: AllRecipes },
- { path: "/recipes/debugger", component: ScraperDebugger },
- { path: "/user/:id/favorites", component: Favorites },
- { path: "/recipes/tag/:tag", component: CategoryTagPage },
- { path: "/recipes/tag", component: CategoryTagPage },
- { path: "/recipes/category", component: CategoryTagPage },
- { path: "/recipes/category/:category", component: CategoryTagPage },
- // Misc
- { path: "/new/", component: NewRecipe },
- { path: "/pages/:customPage", component: CustomPage },
-
- // Recipe Page
- {
- path: "/recipe/:recipe",
- component: ViewRecipe,
- meta: {
- title: async route => {
- const [response, error] = await api.recipes.requestDetails(route.params.recipe);
- if (error) console.log({ error });
- const recipe = response.data;
- if (recipe && recipe.name) return recipe.name;
- else return null;
- },
- },
- },
-];
diff --git a/frontend.old/src/store/index.js b/frontend.old/src/store/index.js
deleted file mode 100644
index 4ce1d97653ae..000000000000
--- a/frontend.old/src/store/index.js
+++ /dev/null
@@ -1,80 +0,0 @@
-import Vue from "vue";
-import Vuex from "vuex";
-import { api } from "@/api";
-import createPersistedState from "vuex-persistedstate";
-import userSettings from "./modules/userSettings";
-import language from "./modules/language";
-import siteSettings from "./modules/siteSettings";
-import recipes from "./modules/recipes";
-import groups from "./modules/groups";
-import snackbar from "./modules/snackbar";
-
-Vue.use(Vuex);
-
-const store = new Vuex.Store({
- plugins: [
- createPersistedState({
- paths: ["userSettings", "siteSettings"],
- }),
- ],
- modules: {
- userSettings,
- language,
- siteSettings,
- groups,
- recipes,
- snackbar,
- },
- state: {
- // All Recipe Data Store
- recentRecipes: [],
- allRecipes: [],
- mealPlanCategories: [],
- allCategories: [],
- allTags: [],
- appInfo: {
- version: "",
- demoStatus: false,
- },
- },
-
- mutations: {
- setMealPlanCategories(state, payload) {
- state.mealPlanCategories = payload;
- },
- setAllCategories(state, payload) {
- state.allCategories = payload;
- },
- setAllTags(state, payload) {
- state.allTags = payload;
- },
- setAppInfo(state, payload) {
- state.appInfo = payload;
- },
- },
-
- actions: {
- async requestCategories({ commit }) {
- const categories = await api.categories.getAll();
- commit("setAllCategories", categories);
- },
- async requestTags({ commit }) {
- const tags = await api.tags.getAll();
- commit("setAllTags", tags);
- },
- async requestAppInfo({ commit }) {
- const response = await api.meta.getAppInfo();
- commit("setAppInfo", response);
- },
- },
-
- getters: {
- getMealPlanCategories: state => state.mealPlanCategories,
- getAllCategories: state => state.allCategories.sort((a, b) => (a.slug > b.slug ? 1 : -1)),
- getAllTags: state => state.allTags.sort((a, b) => (a.slug > b.slug ? 1 : -1)),
- getAppInfo: state => state.appInfo,
- },
-});
-
-export default store;
-export { store };
diff --git a/frontend.old/src/store/modules/groups.js b/frontend.old/src/store/modules/groups.js
deleted file mode 100644
index 03e66fc80dc9..000000000000
--- a/frontend.old/src/store/modules/groups.js
+++ /dev/null
@@ -1,39 +0,0 @@
-import { api } from "@/api";
-
-const state = {
- groups: [],
- currentGroup: {},
-};
-
-const mutations = {
- setGroups(state, payload) {
- state.groups = payload;
- },
- setCurrentGroup(state, payload) {
- state.currentGroup = payload;
- },
-};
-
-const actions = {
- async requestAllGroups({ commit }) {
- const groups = await api.groups.allGroups();
- commit("setGroups", groups);
- },
- async requestCurrentGroup({ commit }) {
- const group = await api.groups.current();
- commit("setCurrentGroup", group);
- },
-};
-
-const getters = {
- getGroups: state => state.groups,
- getGroupNames: state => Array.from(state.groups, x => x.name),
- getCurrentGroup: state => state.currentGroup,
-};
-
-export default {
- state,
- mutations,
- actions,
- getters,
-};
diff --git a/frontend.old/src/store/modules/homePage.js b/frontend.old/src/store/modules/homePage.js
deleted file mode 100644
index c7b2112b49a4..000000000000
--- a/frontend.old/src/store/modules/homePage.js
+++ /dev/null
@@ -1,44 +0,0 @@
-import { api } from "@/api";
-
-const state = {
- showRecent: true,
- showLimit: 9,
- categories: [],
- homeCategories: [],
-};
-
-const mutations = {
- setShowRecent(state, payload) {
- state.showRecent = payload;
- },
- setShowLimit(state, payload) {
- state.showLimit = payload;
- },
- setCategories(state, payload) {
- state.categories = payload.sort((a, b) => (a.name > b.name ? 1 : -1));
- },
- setHomeCategories(state, payload) {
- state.homeCategories = payload;
- },
-};
-
-const actions = {
- async requestHomePageSettings() {
- let categories = await api.categories.get_all();
- this.commit("setCategories", categories);
- },
-};
-
-const getters = {
- getShowRecent: state => state.showRecent,
- getShowLimit: state => state.showLimit,
- getCategories: state => state.categories,
- getHomeCategories: state => state.homeCategories,
-};
-
-export default {
- state,
- mutations,
- actions,
- getters,
-};
diff --git a/frontend.old/src/store/modules/language.js b/frontend.old/src/store/modules/language.js
deleted file mode 100644
index c9d4ea6c4815..000000000000
--- a/frontend.old/src/store/modules/language.js
+++ /dev/null
@@ -1,54 +0,0 @@
-// This is the data store for the options for language selection. Property is reference only, you cannot set this property.
-const state = {
- allLangs: [
- {
- name: "American English",
- value: "en-US",
- },
- {
- name: "British English",
- value: "en-GB",
- },
- {
- name: "Deutsch (German)",
- value: "de-DE",
- },
- {
- name: "Español (Spanish)",
- value: "es-ES",
- },
- {
- name: "Français (French)",
- value: "fr-FR",
- },
- {
- name: "Italiano (Italian)",
- value: "it-IT",
- },
- {
- name: "Nederlands (Dutch)",
- value: "nl-NL",
- },
- {
- name: "Polski (Polish)",
- value: "pl-PL",
- },
- {
- name: "Svenska (Swedish)",
- value: "sv-SE",
- },
- {
- name: "简体中文 (Chinese simplified)",
- value: "zh-CN",
- },
- ],
-};
-
-const getters = {
- getAllLangs: state => state.allLangs,
-};
-
-export default {
- state,
- getters,
-};
diff --git a/frontend.old/src/store/modules/recipes.js b/frontend.old/src/store/modules/recipes.js
deleted file mode 100644
index f2270eb941f2..000000000000
--- a/frontend.old/src/store/modules/recipes.js
+++ /dev/null
@@ -1,76 +0,0 @@
-import { api } from "@/api";
-import Vue from "vue";
-import { recipe } from "@/utils/recipe";
-
-const state = {
- recentRecipes: [],
- allRecipes: [],
-};
-
-const mutations = {
- setRecentRecipes(state, payload) {
- state.recentRecipes = payload;
- },
- patchRecentRecipes(state, payload) {
- if (state.recentRecipes[payload.id]) {
- state.recentRecipes[payload.id] = payload;
- }
- },
- dropRecentRecipes(state, payload) {
- if (state.recentRecipes[payload.id]) {
- Vue.delete(state.recentRecipes, payload.id);
- }
- },
- setAllRecipes(state, payload) {
- state.allRecipes = payload;
- },
- patchAllRecipes(state, payload) {
- state.allRecipes[payload.id] = payload;
- },
- dropAllRecipes(state, payload) {
- if (state.allRecipes[payload.id]) {
- Vue.delete(state.allRecipes, payload.id);
- }
- },
-};
-
-const actions = {
- async requestRecentRecipes() {
- const payload = await api.recipes.allSummary(0, 30);
- const hash = Object.fromEntries(payload.map(e => [e.id, e]));
- this.commit("setRecentRecipes", hash);
- },
- async requestAllRecipes({ getters }) {
- const all = getters.getAllRecipes;
- const payload = await api.recipes.allSummary(all.length, 9999);
- const hash = Object.fromEntries([...all, ...payload].map(e => [e.id, e]));
-
- this.commit("setAllRecipes", hash);
- },
- patchRecipe({ commit }, payload) {
- commit("patchAllRecipes", payload);
- commit("patchRecentRecipes", payload);
- },
- dropRecipe({ commit }, payload) {
- commit("dropAllRecipes", payload);
- commit("dropRecentRecipes", payload);
- },
-};
-
-const getters = {
- getAllRecipes: state => Object.values(state.allRecipes),
- getAllRecipesHash: state => state.allRecipes,
- getRecentRecipes: state => {
- let list = Object.values(state.recentRecipes);
- recipe.sortByUpdated(list);
- return list;
- },
- getRecentRecipesHash: state => state.recentRecipes,
-};
-
-export default {
- state,
- mutations,
- actions,
- getters,
-};
diff --git a/frontend.old/src/store/modules/siteSettings.js b/frontend.old/src/store/modules/siteSettings.js
deleted file mode 100644
index 3095830d0ede..000000000000
--- a/frontend.old/src/store/modules/siteSettings.js
+++ /dev/null
@@ -1,47 +0,0 @@
-import { api } from "@/api";
-import { loadLanguageAsync } from "@/i18n"
-
-const state = {
- siteSettings: {
- language: "en-US",
- firstDayOfWeek: 0,
- showRecent: true,
- cardsPerSection: 9,
- categories: [],
- },
- customPages: [],
-};
-
-const mutations = {
- setSettings(state, payload) {
- state.siteSettings = payload;
- loadLanguageAsync(payload.language);
- },
- setCustomPages(state, payload) {
- state.customPages = payload;
- },
-};
-
-const actions = {
- async requestSiteSettings({ commit }) {
- let settings = await api.siteSettings.get();
- commit("setSettings", settings);
- },
- async requestCustomPages({ commit }) {
- const customPages = await api.siteSettings.getPages();
- commit("setCustomPages", customPages);
- },
-};
-
-const getters = {
- getActiveLang: state => state.siteSettings.language,
- getSiteSettings: state => state.siteSettings,
- getCustomPages: state => state.customPages,
-};
-
-export default {
- state,
- mutations,
- actions,
- getters,
-};
diff --git a/frontend.old/src/store/modules/snackbar.js b/frontend.old/src/store/modules/snackbar.js
deleted file mode 100644
index 21ae1a3982af..000000000000
--- a/frontend.old/src/store/modules/snackbar.js
+++ /dev/null
@@ -1,23 +0,0 @@
-const state = {
- snackbar: {
- open: false,
- text: "Hello From The Store",
- color: "info",
- },
-};
-
-const mutations = {
- setSnackbar(state, payload) {
- state.snackbar = payload;
- },
-};
-
-const getters = {
- getSnackbar: state => state.snackbar,
-};
-
-export default {
- state,
- mutations,
- getters,
-};
diff --git a/frontend.old/src/store/modules/userSettings.js b/frontend.old/src/store/modules/userSettings.js
deleted file mode 100644
index 39337cf93433..000000000000
--- a/frontend.old/src/store/modules/userSettings.js
+++ /dev/null
@@ -1,121 +0,0 @@
-import { api } from "@/api";
-import Vuetify from "@/plugins/vuetify";
-import axios from "axios";
-
-function inDarkMode(payload) {
- let isDark;
-
- if (payload === "system") {
- //Get System Preference from browser
- const darkMediaQuery = window.matchMedia("(prefers-color-scheme: dark)");
- isDark = darkMediaQuery.matches;
- } else if (payload === "dark") isDark = true;
- else if (payload === "light") isDark = false;
-
- return isDark;
-}
-
-const state = {
- activeTheme: {},
- darkMode: "light", // light, dark, system
- isDark: false,
- isLoggedIn: false,
- token: "",
- userData: {},
-};
-
-const mutations = {
- setTheme(state, payload) {
- Vuetify.framework.theme.themes.dark = payload.colors;
- Vuetify.framework.theme.themes.light = payload.colors;
- state.activeTheme = payload;
- },
- setDarkMode(state, payload) {
- let isDark = inDarkMode(payload);
-
- if (isDark !== null) {
- Vuetify.framework.theme.dark = isDark;
- state.isDark = isDark;
- state.darkMode = payload;
- }
- },
- setIsLoggedIn(state, payload) {
- state.isLoggedIn = payload;
- },
- setToken(state, payload) {
- state.isLoggedIn = true;
- axios.defaults.headers.common["Authorization"] = `Bearer ${payload}`;
- state.token = payload;
- },
-
- setUserData(state, payload) {
- state.userData = payload;
- },
-};
-
-const actions = {
- async requestUserData({ getters, commit }) {
- if (getters.getIsLoggedIn) {
- const [response, err] = await api.users.self();
-
- if (err) {
- return; // TODO: Log or Notifty User of Error
- }
-
- commit("setUserData", response.data);
- }
- },
-
- async resetTheme({ commit }) {
- const defaultTheme = await api.themes.requestByName(1);
- if (defaultTheme.colors) {
- Vuetify.framework.theme.themes.dark = defaultTheme.colors;
- Vuetify.framework.theme.themes.light = defaultTheme.colors;
- commit("setTheme", defaultTheme);
- }
- },
-
- async refreshToken({ commit, getters }) {
- if (!getters.getIsLoggedIn) {
- commit("setIsLoggedIn", false); // This has to be here... for some reasons? ¯\_(ツ)_/¯
- console.log("Not Logged In");
- return;
- }
-
- const [response, err] = await api.users.refresh();
-
- if (err) {
- console.log("Failed Token Refresh, Logging Out...");
- commit("setIsLoggedIn", false);
- }
-
- commit("setToken", response.data.access_token);
- },
-
- async initTheme({ dispatch, getters }) {
- //If theme is empty resetTheme
- if (Object.keys(getters.getActiveTheme).length === 0) {
- await dispatch("resetTheme");
- } else {
- Vuetify.framework.theme.dark = inDarkMode(getters.getDarkMode);
- Vuetify.framework.theme.themes.dark = getters.getActiveTheme.colors;
- Vuetify.framework.theme.themes.light = getters.getActiveTheme.colors;
- }
- },
-};
-
-const getters = {
- getActiveTheme: state => state.activeTheme,
- getDarkMode: state => state.darkMode,
- getIsDark: state => state.isDark,
- getIsLoggedIn: state => state.isLoggedIn,
- getToken: state => state.token,
- getUserData: state => state.userData,
-};
-
-export default {
- state,
- mutations,
- actions,
- getters,
-};
diff --git a/frontend.old/src/sw.js b/frontend.old/src/sw.js
deleted file mode 100644
index 4b1037930aa1..000000000000
--- a/frontend.old/src/sw.js
+++ /dev/null
@@ -1,75 +0,0 @@
-/* eslint-disable no-undef, no-underscore-dangle, no-restricted-globals */
-
-self.addEventListener("install", event => {
- event.waitUntil(preLoad());
-});
-
-var preLoad = async () => {
- console.log("Installing web app");
- const cache = await caches.open("offline");
- console.log("caching index and important routes");
- return await cache.addAll(["/", "/recipes/all"]);
-};
-
-self.addEventListener("fetch", event => {
- event.respondWith(
- checkResponse(event.request).catch(() => {
- return returnFromCache(event.request);
- })
- );
- event.waitUntil(addToCache(event.request));
-});
-
-var checkResponse = request => {
- return new Promise(function(fulfill, reject) {
- fetch(request).then(function(response) {
- if (response.status !== 404) {
- fulfill(response);
- } else {
- reject();
- }
- }, reject);
- });
-};
-
-var addToCache = async request => {
- const cache = await caches.open("offline");
- const response = await fetch(request);
- console.log(response.url + " was cached");
- return await cache.put(request, response);
-};
-
-var returnFromCache = async request => {
- const cache = await caches.open("offline");
- const matching = await cache.match(request);
- if (!matching || matching.status == 404) {
- return cache.match("offline.html");
- } else {
- return matching;
- }
-};
-
-// This is the code piece that GenerateSW mode can't provide for us.
-// This code listens for the user's confirmation to update the app.
-self.addEventListener("message", e => {
- if (!e.data) {
- return;
- }
-
- switch (e.data) {
- case "skipWaiting":
- self.skipWaiting();
- break;
- default:
- // NOOP
- break;
- }
-});
-
-workbox.core.clientsClaim(); // Vue CLI 4 and Workbox v4, else
-// workbox.clientsClaim(); // Vue CLI 3 and Workbox v3.
-
-// The precaching code provided by Workbox.
-self.__precacheManifest = [].concat(self.__precacheManifest || []);
-// workbox.precaching.suppressWarnings(); // Only used with Vue CLI 3 and Workbox v3.
-workbox.precaching.precacheAndRoute(self.__precacheManifest, {});
diff --git a/frontend.old/vue.config.js b/frontend.old/vue.config.js
deleted file mode 100644
index 442baa0130e5..000000000000
--- a/frontend.old/vue.config.js
+++ /dev/null
@@ -1,50 +0,0 @@
-const path = require("path");
-const manifestJSON = require("./public/manifest.json");
-const PreloadWebpackPlugin = require("preload-webpack-plugin");
-
-module.exports = {
- transpileDependencies: ["vuetify"],
- publicPath: process.env.NODE_ENV === "production" ? "/" : "/",
- outputDir: process.env.NODE_ENV === "production" ? "./dist" : "../mealie/web",
- devServer: {
- proxy: {
- "/api": {
- target: process.env.VUE_APP_API_BASE_URL,
- secure: false,
- },
- },
- },
- pluginOptions: {
- i18n: {
- locale: "en",
- fallbackLocale: "en",
- localeDir: "locales",
- enableInSFC: true,
- },
- webpackBundleAnalyzer: {
- openAnalyzer: process.env.PREVIEW_BUNDLE,
- },
- },
- configureWebpack: {
- resolve: {
- alias: {
- "@": path.resolve("src"),
- },
- plugins: [new PreloadWebpackPlugin({})],
- },
- },
- pwa: {
- name: manifestJSON.short_name,
- themeColor: manifestJSON.theme_color,
- msTileColor: manifestJSON.background_color,
- appleMobileWebAppCapable: "yes",
- appleMobileWebAppStatusBarStyle: "black",
- manifestCrossorigin: "use-credentials",
-
- workboxPluginMode: "InjectManifest",
- workboxOptions: {
- swSrc: "./src/sw.js",
- swDest: "service-worker.js",
- },
- },
-};
diff --git a/frontend/components/Domain/Recipe/RecipeDialogBulkAdd.vue b/frontend/components/Domain/Recipe/RecipeDialogBulkAdd.vue
index bc893174ed5f..ad5385c5aff8 100644
--- a/frontend/components/Domain/Recipe/RecipeDialogBulkAdd.vue
+++ b/frontend/components/Domain/Recipe/RecipeDialogBulkAdd.vue
@@ -40,8 +40,8 @@
diff --git a/frontend/pages/user/profile/edit.vue b/frontend/pages/user/profile/edit.vue
index cabfc34875b0..810f925fd8e0 100644
--- a/frontend/pages/user/profile/edit.vue
+++ b/frontend/pages/user/profile/edit.vue
@@ -73,7 +73,7 @@
-
+
@@ -164,28 +164,6 @@ export default defineComponent({
title: this.$t("settings.profile") as string,
};
},
-
- methods: {
- async changePassword() {
- // @ts-ignore
- this.paswordLoading = true;
- const data = {
- currentPassword: this.password.current,
- newPassword: this.password.newOne,
- };
-
- // @ts-ignore
- if (this.$refs.passChange.validate()) {
- // @ts-ignore
- if (await api.users.changePassword(this.user.id, data)) {
- this.$emit("refresh");
- }
- }
-
- // @ts-ignore
- this.paswordLoading = false;
- },
- },
});
diff --git a/makefile b/makefile
index 8763736d95b5..fe0ecc5a0ed6 100644
--- a/makefile
+++ b/makefile
@@ -69,14 +69,15 @@ coverage: ## ☂️ Check code coverage quickly with the default Python
poetry run coverage html
$(BROWSER) htmlcov/index.html
+.PHONY: setup
setup: ## 🏗 Setup Development Instance
- cp template.env .env -n
poetry install && \
cd frontend && \
- cp template.env .env -n
yarn install && \
cd ..
+ echo "Be sure to copy the template.env files"
+
backend: ## 🎬 Start Mealie Backend Development Server
poetry run python mealie/db/init_db.py && \
poetry run python mealie/services/image/minify.py && \
diff --git a/mealie/db/data_access_layer/access_model_factory.py b/mealie/db/data_access_layer/access_model_factory.py
index 5dabf64b53ff..04fc5e79f765 100644
--- a/mealie/db/data_access_layer/access_model_factory.py
+++ b/mealie/db/data_access_layer/access_model_factory.py
@@ -14,11 +14,9 @@ from mealie.db.models.recipe.ingredient import IngredientFoodModel, IngredientUn
from mealie.db.models.recipe.recipe import RecipeModel
from mealie.db.models.recipe.tag import Tag
from mealie.db.models.server.task import ServerTaskModel
-from mealie.db.models.settings import SiteSettings
from mealie.db.models.sign_up import SignUp
from mealie.db.models.users import LongLiveToken, User
from mealie.db.models.users.password_reset import PasswordResetModel
-from mealie.schema.admin import SiteSettings as SiteSettingsSchema
from mealie.schema.cookbook.cookbook import ReadCookBook
from mealie.schema.events import Event as EventSchema
from mealie.schema.events import EventNotificationIn
@@ -94,10 +92,6 @@ class Database:
# ================================================================
# Site Items
- @cached_property
- def settings(self) -> AccessModel[SiteSettingsSchema, SiteSettings]:
- return AccessModel(self.session, pk_id, SiteSettings, SiteSettingsSchema)
-
@cached_property
def sign_up(self) -> AccessModel[SignUpOut, SignUp]:
return AccessModel(self.session, pk_id, SignUp, SignUpOut)
diff --git a/mealie/db/init_db.py b/mealie/db/init_db.py
index 5f960eb12dff..c63c7a946a53 100644
--- a/mealie/db/init_db.py
+++ b/mealie/db/init_db.py
@@ -6,7 +6,6 @@ from mealie.db.data_initialization.init_users import default_user_init
from mealie.db.database import get_database
from mealie.db.db_setup import create_session, engine
from mealie.db.models._model_base import SqlAlchemyBase
-from mealie.schema.admin import SiteSettings
from mealie.schema.user.user import GroupBase
from mealie.services.events import create_general_event
from mealie.services.group_services.group_utils import create_new_group
@@ -24,16 +23,10 @@ def create_all_models():
def init_db(db: Database) -> None:
default_group_init(db)
- default_settings_init(db)
default_user_init(db)
default_recipe_unit_init(db)
-def default_settings_init(db: Database):
- document = db.settings.create(SiteSettings().dict())
- logger.info(f"Created Site Settings: \n {document}")
-
-
def default_group_init(db: Database):
logger.info("Generating Default Group")
create_new_group(db, GroupBase(name=settings.DEFAULT_GROUP))
diff --git a/mealie/db/models/_all_models.py b/mealie/db/models/_all_models.py
index 7cb43654f344..02c4986b6a51 100644
--- a/mealie/db/models/_all_models.py
+++ b/mealie/db/models/_all_models.py
@@ -2,6 +2,5 @@ from .event import *
from .group import *
from .recipe.recipe import *
from .server import *
-from .settings import *
from .sign_up import *
from .users import *
diff --git a/mealie/db/models/_model_base.py b/mealie/db/models/_model_base.py
index 907eb90ca97d..fc8d93bfa39a 100644
--- a/mealie/db/models/_model_base.py
+++ b/mealie/db/models/_model_base.py
@@ -19,9 +19,6 @@ class BaseMixins:
`cls.get_ref` method which will return the object from the database or none. Useful for many-to-many relationships.
"""
- class Config:
- get_attr = "id"
-
def update(self, *args, **kwarg):
self.__init__(*args, **kwarg)
diff --git a/mealie/db/models/_model_utils.py b/mealie/db/models/_model_utils.py
deleted file mode 100644
index c0f15881afb6..000000000000
--- a/mealie/db/models/_model_utils.py
+++ /dev/null
@@ -1,119 +0,0 @@
-from functools import wraps
-from typing import Union
-
-from sqlalchemy.orm import MANYTOMANY, MANYTOONE, ONETOMANY
-
-
-def handle_one_to_many_list(get_attr, relation_cls, all_elements: list[dict]):
- elems_to_create = []
- updated_elems = []
-
- for elem in all_elements:
- elem_id = elem.get(get_attr, None)
-
- existing_elem = relation_cls.get_ref(match_value=elem_id)
-
- if existing_elem is None:
-
- elems_to_create.append(elem)
-
- else:
- for key, value in elem.items():
- setattr(existing_elem, key, value)
-
- updated_elems.append(existing_elem)
-
- new_elems = []
- for elem in elems_to_create:
- new_elems = [relation_cls(**elem) for elem in all_elements]
-
- return new_elems
-
-
-def auto_init(exclude: Union[set, list] = None): # sourcery no-metrics
- """Wraps the `__init__` method of a class to automatically set the common
- attributes.
-
- Args:
- exclude (Union[set, list], optional): [description]. Defaults to None.
- """
-
- exclude = exclude or set()
- exclude.add("id")
-
- def decorator(init):
- @wraps(init)
- def wrapper(self, *args, **kwargs): # sourcery no-metrics
- """
- Custom initializer that allows nested children initialization.
- Only keys that are present as instance's class attributes are allowed.
- These could be, for example, any mapped columns or relationships.
-
- Code inspired from GitHub.
- Ref: https://github.com/tiangolo/fastapi/issues/2194
- """
- cls = self.__class__
- model_columns = self.__mapper__.columns
- relationships = self.__mapper__.relationships
-
- session = kwargs.get("session", None)
-
- for key, val in kwargs.items():
- if key in exclude:
- continue
-
- if not hasattr(cls, key):
- continue
- # raise TypeError(f"Invalid keyword argument: {key}")
-
- if key in model_columns:
- setattr(self, key, val)
- continue
-
- if key in relationships:
- relation_dir = relationships[key].direction.name
- relation_cls = relationships[key].mapper.entity
- use_list = relationships[key].uselist
-
- try:
- get_attr = relation_cls.Config.get_attr
- if get_attr is None:
- get_attr = "id"
- except Exception:
- get_attr = "id"
-
- if relation_dir == ONETOMANY.name and use_list:
- instances = handle_one_to_many_list(get_attr, relation_cls, val)
- setattr(self, key, instances)
-
- if relation_dir == ONETOMANY.name and not use_list:
- instance = relation_cls(**val)
- setattr(self, key, instance)
-
- elif relation_dir == MANYTOONE.name and not use_list:
- if isinstance(val, dict):
- val = val.get(get_attr)
-
- if val is None:
- raise ValueError(f"Expected 'id' to be provided for {key}")
-
- if isinstance(val, (str, int)):
- instance = relation_cls.get_ref(match_value=val, session=session)
- setattr(self, key, instance)
-
- elif relation_dir == MANYTOMANY.name:
-
- if not isinstance(val, list):
- raise ValueError(f"Expected many to many input to be of type list for {key}")
-
- if len(val) > 0 and isinstance(val[0], dict):
- val = [elem.get(get_attr) for elem in val]
-
- instances = [x for x in [relation_cls.get_ref(elem, session=session) for elem in val] if x]
- setattr(self, key, instances)
-
- return init(self, *args, **kwargs)
-
- return wrapper
-
- return decorator
diff --git a/mealie/db/models/_model_utils/__init__.py b/mealie/db/models/_model_utils/__init__.py
new file mode 100644
index 000000000000..9949173723f8
--- /dev/null
+++ b/mealie/db/models/_model_utils/__init__.py
@@ -0,0 +1 @@
+from .auto_init import auto_init
diff --git a/mealie/db/models/_model_utils/auto_init.py b/mealie/db/models/_model_utils/auto_init.py
new file mode 100644
index 000000000000..120c94803fc9
--- /dev/null
+++ b/mealie/db/models/_model_utils/auto_init.py
@@ -0,0 +1,184 @@
+from __future__ import annotations
+
+from functools import wraps
+
+from pydantic import BaseModel, Field
+from sqlalchemy.orm import MANYTOMANY, MANYTOONE, ONETOMANY, Session
+from sqlalchemy.orm.decl_api import DeclarativeMeta
+from sqlalchemy.orm.mapper import Mapper
+from sqlalchemy.orm.relationships import RelationshipProperty
+from sqlalchemy.sql.base import ColumnCollection
+from sqlalchemy.util._collections import ImmutableProperties
+
+from .helpers import safe_call
+
+
+def _default_exclusion() -> set[str]:
+ return {"id"}
+
+
+class AutoInitConfig(BaseModel):
+ """
+ Config class for `auto_init` decorator.
+ """
+
+ get_attr: str = None
+ exclude: set = Field(default_factory=_default_exclusion)
+ # auto_create: bool = False
+
+
+def _get_config(relation_cls: DeclarativeMeta) -> AutoInitConfig:
+ """
+ Returns the config for the given class.
+ """
+ cfg = AutoInitConfig()
+ cfgKeys = cfg.dict().keys()
+ # Get the config for the class
+ try:
+ class_config: AutoInitConfig = relation_cls.Config
+ except AttributeError:
+ return cfg
+ # Map all matching attributes in Config to all AutoInitConfig attributes
+ for attr in dir(class_config):
+ if attr in cfgKeys:
+ setattr(cfg, attr, getattr(class_config, attr))
+
+ return cfg
+
+
+def get_lookup_attr(relation_cls: DeclarativeMeta) -> str:
+ """Returns the primary key attribute of the related class as a string.
+
+ Args:
+ relation_cls (DeclarativeMeta): The SQLAlchemy class to get the primary_key from
+
+ Returns:
+ Any: [description]
+ """
+
+ cfg = _get_config(relation_cls)
+
+ try:
+ get_attr = cfg.get_attr
+ if get_attr is None:
+ get_attr = relation_cls.__table__.primary_key.columns.keys()[0]
+ except Exception:
+ get_attr = "id"
+ return get_attr
+
+
+def handle_many_to_many(session, get_attr, relation_cls, all_elements: list[dict]):
+ """
+ Proxy call to `handle_one_to_many_list` for many-to-many relationships. Because functionally, they do the same
+ """
+ return handle_one_to_many_list(session, get_attr, relation_cls, all_elements)
+
+
+def handle_one_to_many_list(session: Session, get_attr, relation_cls, all_elements: list[dict]):
+ elems_to_create: list[dict] = []
+ updated_elems: list[dict] = []
+
+ for elem in all_elements:
+ elem_id = elem.get(get_attr, None)
+
+ existing_elem = session.query(relation_cls).filter_by(**{get_attr: elem_id}).one_or_none()
+
+ if existing_elem is None:
+ elems_to_create.append(elem)
+
+ else:
+ for key, value in elem.items():
+ setattr(existing_elem, key, value)
+
+ updated_elems.append(existing_elem)
+
+ new_elems = [safe_call(relation_cls, elem) for elem in elems_to_create]
+ return new_elems + updated_elems
+
+
+def auto_init(): # sourcery no-metrics
+ """Wraps the `__init__` method of a class to automatically set the common
+ attributes.
+
+ Args:
+ exclude (Union[set, list], optional): [description]. Defaults to None.
+ """
+
+ def decorator(init):
+ @wraps(init)
+ def wrapper(self: DeclarativeMeta, *args, **kwargs): # sourcery no-metrics
+ """
+ Custom initializer that allows nested children initialization.
+ Only keys that are present as instance's class attributes are allowed.
+ These could be, for example, any mapped columns or relationships.
+
+ Code inspired from GitHub.
+ Ref: https://github.com/tiangolo/fastapi/issues/2194
+ """
+ cls = self.__class__
+
+ exclude = _get_config(cls).exclude
+
+ alchemy_mapper: Mapper = self.__mapper__
+ model_columns: ColumnCollection = alchemy_mapper.columns
+ relationships: ImmutableProperties = alchemy_mapper.relationships
+
+ session = kwargs.get("session", None)
+
+ if session is None:
+ raise ValueError("Session is required to initialize the model with `auto_init`")
+
+ for key, val in kwargs.items():
+ if key in exclude:
+ continue
+
+ if not hasattr(cls, key):
+ continue
+ # raise TypeError(f"Invalid keyword argument: {key}")
+
+ if key in model_columns:
+ setattr(self, key, val)
+ continue
+
+ if key in relationships:
+ prop: RelationshipProperty = relationships[key]
+
+ # Identifies the type of relationship (ONETOMANY, MANYTOONE, many-to-one, many-to-many)
+ relation_dir = prop.direction
+
+ # Identifies the parent class of the related object.
+ relation_cls: DeclarativeMeta = prop.mapper.entity
+
+ # Identifies if the relationship was declared with use_list=True
+ use_list: bool = prop.uselist
+
+ get_attr = get_lookup_attr(relation_cls)
+
+ if relation_dir == ONETOMANY and use_list:
+ instances = handle_one_to_many_list(session, get_attr, relation_cls, val)
+ setattr(self, key, instances)
+
+ elif relation_dir == ONETOMANY:
+ instance = safe_call(relation_cls, val)
+ setattr(self, key, instance)
+
+ elif relation_dir == MANYTOONE and not use_list:
+ if isinstance(val, dict):
+ val = val.get(get_attr)
+
+ if val is None:
+ raise ValueError(f"Expected 'id' to be provided for {key}")
+
+ if isinstance(val, (str, int)):
+ instance = session.query(relation_cls).filter_by(**{get_attr: val}).one_or_none()
+ setattr(self, key, instance)
+
+ elif relation_dir == MANYTOMANY:
+ instances = handle_many_to_many(session, get_attr, relation_cls, val)
+ setattr(self, key, instances)
+
+ return init(self, *args, **kwargs)
+
+ return wrapper
+
+ return decorator
diff --git a/mealie/db/models/_model_utils/helpers.py b/mealie/db/models/_model_utils/helpers.py
new file mode 100644
index 000000000000..fa0f56c1e592
--- /dev/null
+++ b/mealie/db/models/_model_utils/helpers.py
@@ -0,0 +1,39 @@
+import inspect
+from typing import Any, Callable
+
+
+def get_valid_call(func: Callable, args_dict) -> dict:
+ """
+ Returns a dictionary of valid arguemnts for the supplied function. if kwargs are accepted,
+ the original dictionary will be returned.
+ """
+
+ def get_valid_args(func: Callable) -> tuple:
+ """
+ Returns a tuple of valid arguemnts for the supplied function.
+ """
+ return inspect.getfullargspec(func).args
+
+ def accepts_kwargs(func: Callable) -> bool:
+ """
+ Returns True if the function accepts keyword arguments.
+ """
+ return inspect.getfullargspec(func).varkw is not None
+
+ if accepts_kwargs(func):
+ return args_dict
+
+ valid_args = get_valid_args(func)
+
+ return {k: v for k, v in args_dict.items() if k in valid_args}
+
+
+def safe_call(func, dict) -> Any:
+ """
+ Safely calls the supplied function with the supplied dictionary of arguments.
+ by removing any invalid arguments.
+ """
+ try:
+ return func(**get_valid_call(func, dict))
+ except TypeError:
+ return func(**dict)
diff --git a/mealie/db/models/group/group.py b/mealie/db/models/group/group.py
index fdc52e4cbb31..21629c055f4f 100644
--- a/mealie/db/models/group/group.py
+++ b/mealie/db/models/group/group.py
@@ -46,7 +46,10 @@ class Group(SqlAlchemyBase, BaseMixins):
server_tasks = orm.relationship(ServerTaskModel, back_populates="group", single_parent=True)
shopping_lists = orm.relationship("ShoppingList", back_populates="group", single_parent=True)
- @auto_init({"users", "webhooks", "shopping_lists", "cookbooks", "preferences", "invite_tokens", "mealplans"})
+ class Config:
+ exclude = {"users", "webhooks", "shopping_lists", "cookbooks", "preferences", "invite_tokens", "mealplans"}
+
+ @auto_init()
def __init__(self, **_) -> None:
pass
diff --git a/mealie/db/models/recipe/assets.py b/mealie/db/models/recipe/assets.py
index 196c65c93d88..8f18a2d4dc45 100644
--- a/mealie/db/models/recipe/assets.py
+++ b/mealie/db/models/recipe/assets.py
@@ -11,12 +11,7 @@ class RecipeAsset(SqlAlchemyBase):
icon = sa.Column(sa.String)
file_name = sa.Column(sa.String)
- def __init__(
- self,
- name=None,
- icon=None,
- file_name=None,
- ) -> None:
+ def __init__(self, name=None, icon=None, file_name=None) -> None:
self.name = name
self.file_name = file_name
self.icon = icon
diff --git a/mealie/db/models/recipe/category.py b/mealie/db/models/recipe/category.py
index f4f320dcbc30..7aa7aaef7ca4 100644
--- a/mealie/db/models/recipe/category.py
+++ b/mealie/db/models/recipe/category.py
@@ -8,12 +8,6 @@ from mealie.db.models._model_base import BaseMixins, SqlAlchemyBase
logger = root_logger.get_logger()
-site_settings2categories = sa.Table(
- "site_settings2categories",
- SqlAlchemyBase.metadata,
- sa.Column("site_settings.id", sa.Integer, sa.ForeignKey("site_settings.id")),
- sa.Column("category_id", sa.Integer, sa.ForeignKey("categories.id")),
-)
group2categories = sa.Table(
"group2categories",
diff --git a/mealie/db/models/recipe/recipe.py b/mealie/db/models/recipe/recipe.py
index 2a9365631027..1b4f71f40828 100644
--- a/mealie/db/models/recipe/recipe.py
+++ b/mealie/db/models/recipe/recipe.py
@@ -86,14 +86,7 @@ class RecipeModel(SqlAlchemyBase, BaseMixins):
class Config:
get_attr = "slug"
-
- @validates("name")
- def validate_name(self, key, name):
- assert name != ""
- return name
-
- @auto_init(
- {
+ exclude = {
"assets",
"extras",
"notes",
@@ -103,7 +96,13 @@ class RecipeModel(SqlAlchemyBase, BaseMixins):
"settings",
"tools",
}
- )
+
+ @validates("name")
+ def validate_name(self, key, name):
+ assert name != ""
+ return name
+
+ @auto_init()
def __init__(
self,
session,
@@ -115,7 +114,7 @@ class RecipeModel(SqlAlchemyBase, BaseMixins):
recipe_instructions: list[dict] = None,
settings: dict = None,
tools: list[str] = None,
- **_
+ **_,
) -> None:
self.nutrition = Nutrition(**nutrition) if nutrition else Nutrition()
self.tools = [Tool(tool=x) for x in tools] if tools else []
diff --git a/mealie/db/models/settings.py b/mealie/db/models/settings.py
deleted file mode 100644
index 79464f0bf3a2..000000000000
--- a/mealie/db/models/settings.py
+++ /dev/null
@@ -1,35 +0,0 @@
-import sqlalchemy as sa
-import sqlalchemy.orm as orm
-from sqlalchemy.orm import Session
-
-from mealie.db.models._model_base import BaseMixins, SqlAlchemyBase
-from mealie.db.models.recipe.category import Category, site_settings2categories
-
-
-class SiteSettings(SqlAlchemyBase, BaseMixins):
- __tablename__ = "site_settings"
- id = sa.Column(sa.Integer, primary_key=True)
- language = sa.Column(sa.String)
- first_day_of_week = sa.Column(sa.Integer)
- categories = orm.relationship("Category", secondary=site_settings2categories, single_parent=True)
- show_recent = sa.Column(sa.Boolean, default=True)
- cards_per_section = sa.Column(sa.Integer)
-
- def __init__(
- self,
- session: Session = None,
- language="en",
- first_day_of_week: int = 0,
- categories: list = [],
- show_recent=True,
- cards_per_section: int = 9,
- ) -> None:
- session.commit()
- self.language = language
- self.first_day_of_week = first_day_of_week
- self.cards_per_section = cards_per_section
- self.show_recent = show_recent
- self.categories = [Category.get_ref(session=session, slug=cat.get("slug")) for cat in categories]
-
- def update(self, *args, **kwarg):
- self.__init__(*args, **kwarg)
diff --git a/mealie/db/models/users/users.py b/mealie/db/models/users/users.py
index 77b4f09f1367..916bf6777862 100644
--- a/mealie/db/models/users/users.py
+++ b/mealie/db/models/users/users.py
@@ -11,7 +11,6 @@ settings = get_app_settings()
class LongLiveToken(SqlAlchemyBase, BaseMixins):
__tablename__ = "long_live_tokens"
- id = Column(Integer, primary_key=True)
parent_id = Column(Integer, ForeignKey("users.id"))
name = Column(String, nullable=False)
token = Column(String, nullable=False)
@@ -25,7 +24,6 @@ class LongLiveToken(SqlAlchemyBase, BaseMixins):
class User(SqlAlchemyBase, BaseMixins):
__tablename__ = "users"
- id = Column(Integer, primary_key=True)
full_name = Column(String, index=True)
username = Column(String, index=True, unique=True)
email = Column(String, unique=True, index=True)
@@ -41,7 +39,6 @@ class User(SqlAlchemyBase, BaseMixins):
can_invite = Column(Boolean, default=False)
can_organize = Column(Boolean, default=False)
- # Recipes
tokens: list[LongLiveToken] = orm.relationship(
LongLiveToken, back_populates="user", cascade="all, delete, delete-orphan", single_parent=True
)
@@ -67,67 +64,52 @@ class User(SqlAlchemyBase, BaseMixins):
password,
favorite_recipes: list[str] = None,
group: str = settings.DEFAULT_GROUP,
- admin=False,
advanced=False,
- can_manage=False,
- can_invite=False,
- can_organize=False,
- **_
+ **kwargs
) -> None:
-
group = group or settings.DEFAULT_GROUP
favorite_recipes = favorite_recipes or []
+ self.group = Group.get_ref(session, group)
+
self.full_name = full_name
self.email = email
- self.group = Group.get_ref(session, group)
- self.admin = admin
self.password = password
self.advanced = advanced
- if self.admin:
- self.can_manage = True
- self.can_invite = True
- self.can_organize = True
- else:
- self.can_manage = can_manage
- self.can_invite = can_invite
- self.can_organize = can_organize
-
self.favorite_recipes = []
if self.username is None:
self.username = full_name
- def update(
- self,
- full_name,
- email,
- group,
- admin,
- username,
- session=None,
- favorite_recipes=None,
- password=None,
- advanced=False,
- can_manage=False,
- can_invite=False,
- can_organize=False,
- **_
- ):
+ self._set_permissions(**kwargs)
+
+ def update(self, full_name, email, group, username, session=None, favorite_recipes=None, advanced=False, **kwargs):
favorite_recipes = favorite_recipes or []
self.username = username
self.full_name = full_name
self.email = email
+
self.group = Group.get_ref(session, group)
- self.admin = admin
self.advanced = advanced
if self.username is None:
self.username = full_name
- if password:
- self.password = password
+ self._set_permissions(**kwargs)
+ def update_password(self, password):
+ self.password = password
+
+ def _set_permissions(self, admin, can_manage=False, can_invite=False, can_organize=False, **_):
+ """Set user permissions based on the admin flag and the passed in kwargs
+
+ Args:
+ admin (bool):
+ can_manage (bool):
+ can_invite (bool):
+ can_organize (bool):
+ """
+ self.admin = admin
if self.admin:
self.can_manage = True
self.can_invite = True
@@ -137,9 +119,6 @@ class User(SqlAlchemyBase, BaseMixins):
self.can_invite = can_invite
self.can_organize = can_organize
- def update_password(self, password):
- self.password = password
-
@staticmethod
def get_ref(session, id: str):
return session.query(User).filter(User.id == id).one()
diff --git a/mealie/routes/site_settings/site_settings.py b/mealie/routes/site_settings/site_settings.py
index 23e272e526cd..01dda81a7539 100644
--- a/mealie/routes/site_settings/site_settings.py
+++ b/mealie/routes/site_settings/site_settings.py
@@ -5,7 +5,6 @@ from mealie.core.dependencies import get_current_user
from mealie.db.database import get_database
from mealie.db.db_setup import generate_session
from mealie.routes.routers import AdminAPIRouter
-from mealie.schema.admin import SiteSettings
from mealie.schema.user import GroupInDB, PrivateUser
from mealie.utils.post_webhooks import post_webhooks
@@ -21,16 +20,6 @@ def get_main_settings(session: Session = Depends(generate_session)):
return db.settings.get(1)
-@admin_router.put("")
-def update_settings(
- data: SiteSettings,
- session: Session = Depends(generate_session),
-):
- """ Returns Site Settings """
- db = get_database(session)
- db.settings.update(1, data.dict())
-
-
@admin_router.post("/webhooks/test")
def test_webhooks(
current_user: PrivateUser = Depends(get_current_user),
diff --git a/mealie/routes/users/passwords.py b/mealie/routes/users/passwords.py
index 7986a517fe7e..c760b31359c4 100644
--- a/mealie/routes/users/passwords.py
+++ b/mealie/routes/users/passwords.py
@@ -24,10 +24,9 @@ async def reset_user_password(id: int, session: Session = Depends(generate_sessi
db.users.update_password(id, new_password)
-@user_router.put("/{id}/password")
+@user_router.put("/{item_id}/password")
def update_password(password_change: ChangePassword, user_service: UserService = Depends(UserService.write_existing)):
""" Resets the User Password"""
-
return user_service.change_password(password_change)
diff --git a/mealie/schema/admin/settings.py b/mealie/schema/admin/settings.py
index 4002db51bb8f..31468754bb3f 100644
--- a/mealie/schema/admin/settings.py
+++ b/mealie/schema/admin/settings.py
@@ -4,31 +4,7 @@ from fastapi_camelcase import CamelModel
from pydantic import validator
from slugify import slugify
-from ..recipe.recipe_category import CategoryBase, RecipeCategoryResponse
-
-
-class SiteSettings(CamelModel):
- language: str = "en-US"
- first_day_of_week: int = 0
- show_recent: bool = True
- cards_per_section: int = 9
- categories: Optional[list[CategoryBase]] = []
-
- class Config:
- orm_mode = True
-
- schema_extra = {
- "example": {
- "language": "en",
- "firstDayOfWeek": 0,
- "showRecent": True,
- "categories": [
- {"id": 1, "name": "thanksgiving", "slug": "thanksgiving"},
- {"id": 2, "name": "homechef", "slug": "homechef"},
- {"id": 3, "name": "potatoes", "slug": "potatoes"},
- ],
- }
- }
+from ..recipe.recipe_category import RecipeCategoryResponse
class CustomPageBase(CamelModel):
diff --git a/mealie/services/backups/imports.py b/mealie/services/backups/imports.py
index bf511e3f39d4..3c483bc957b1 100644
--- a/mealie/services/backups/imports.py
+++ b/mealie/services/backups/imports.py
@@ -11,15 +11,7 @@ from mealie.core.config import get_app_dirs
app_dirs = get_app_dirs()
from mealie.db.database import get_database
-from mealie.schema.admin import (
- CommentImport,
- GroupImport,
- NotificationImport,
- RecipeImport,
- SettingsImport,
- SiteSettings,
- UserImport,
-)
+from mealie.schema.admin import CommentImport, GroupImport, NotificationImport, RecipeImport, UserImport
from mealie.schema.events import EventNotificationIn
from mealie.schema.recipe import CommentOut, Recipe
from mealie.schema.user import PrivateUser, UpdateGroup
@@ -181,19 +173,7 @@ class ImportDatabase:
return import_notifications
def import_settings(self):
- settings_file = self.import_dir.joinpath("settings", "settings.json")
- settings = ImportDatabase.read_models_file(settings_file, SiteSettings)
- settings = settings[0]
-
- try:
- self.db.settings.update(1, settings.dict())
- import_status = SettingsImport(name="Site Settings", status=True)
-
- except Exception as inst:
- self.session.rollback()
- import_status = SettingsImport(name="Site Settings", status=False, exception=str(inst))
-
- return [import_status]
+ return []
def import_groups(self):
groups_file = self.import_dir.joinpath("groups", "groups.json")
diff --git a/mealie/services/migrations/_migration_base.py b/mealie/services/migrations/_migration_base.py
index 78659be25681..f39ea2fd1901 100644
--- a/mealie/services/migrations/_migration_base.py
+++ b/mealie/services/migrations/_migration_base.py
@@ -181,7 +181,7 @@ class MigrationBase(BaseModel):
except Exception as inst:
exception = inst
- logger.error(inst)
+ logger.exception(inst)
self.session.rollback()
import_status = MigrationImport(slug=recipe.slug, name=recipe.name, status=status, exception=str(exception))
diff --git a/mealie/services/user_services/user_service.py b/mealie/services/user_services/user_service.py
index 9b8fb38a006e..59f5c692ae2d 100644
--- a/mealie/services/user_services/user_service.py
+++ b/mealie/services/user_services/user_service.py
@@ -13,7 +13,12 @@ class UserService(UserHttpService[int, str]):
event_func = create_user_event
acting_user: PrivateUser = None
+ def populate_item(self, item_id: int) -> None:
+ self.acting_user = self.db.users.get_one(item_id)
+ return self.acting_user
+
def assert_existing(self, id) -> PrivateUser:
+ self.populate_item(id)
self._populate_target_user(id)
self._assert_user_change_allowed()
return self.target_user
@@ -32,7 +37,6 @@ class UserService(UserHttpService[int, str]):
self.target_user = self.acting_user
def change_password(self, password_change: ChangePassword) -> PrivateUser:
- """"""
if not verify_password(password_change.current_password, self.target_user.password):
raise HTTPException(status.HTTP_400_BAD_REQUEST)
diff --git a/poetry.lock b/poetry.lock
index 8ccdf36004f4..a66ab7c783de 100644
--- a/poetry.lock
+++ b/poetry.lock
@@ -41,7 +41,7 @@ six = "*"
[[package]]
name = "apscheduler"
-version = "3.8.0"
+version = "3.8.1"
description = "In-process task scheduler with Cron-like capabilities"
category = "main"
optional = false
@@ -50,7 +50,7 @@ python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*, <4"
[package.dependencies]
pytz = "*"
six = ">=1.4.0"
-tzlocal = ">=2.0,<3.0"
+tzlocal = ">=2.0,<3.0.0 || >=4.0.0"
[package.extras]
asyncio = ["trollius"]
@@ -67,7 +67,7 @@ zookeeper = ["kazoo"]
[[package]]
name = "astroid"
-version = "2.8.3"
+version = "2.8.4"
description = "An abstract syntax tree for Python with inference support."
category = "dev"
optional = false
@@ -646,7 +646,7 @@ i18n = ["babel (>=2.9.0)"]
[[package]]
name = "mkdocs-material"
-version = "7.3.4"
+version = "7.3.6"
description = "A Material Design theme for MkDocs"
category = "dev"
optional = false
@@ -657,7 +657,7 @@ jinja2 = ">=2.11.1"
markdown = ">=3.2"
mkdocs = ">=1.2.3"
mkdocs-material-extensions = ">=1.0"
-pygments = ">=2.4"
+pygments = ">=2.10"
pymdown-extensions = ">=9.0"
[[package]]
@@ -691,14 +691,14 @@ signedtoken = ["cryptography (>=3.0.0,<4)", "pyjwt (>=2.0.0,<3)"]
[[package]]
name = "packaging"
-version = "21.0"
+version = "21.2"
description = "Core utilities for Python packages"
category = "dev"
optional = false
python-versions = ">=3.6"
[package.dependencies]
-pyparsing = ">=2.0.2"
+pyparsing = ">=2.0.2,<3"
[[package]]
name = "passlib"
@@ -1044,6 +1044,17 @@ category = "main"
optional = false
python-versions = "*"
+[[package]]
+name = "pytz-deprecation-shim"
+version = "0.1.0.post0"
+description = "Shims to make deprecation of pytz easier"
+category = "main"
+optional = false
+python-versions = "!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*,!=3.4.*,!=3.5.*,>=2.7"
+
+[package.dependencies]
+tzdata = {version = "*", markers = "python_version >= \"3.6\""}
+
[[package]]
name = "pyyaml"
version = "5.4.1"
@@ -1263,16 +1274,29 @@ category = "main"
optional = false
python-versions = "*"
+[[package]]
+name = "tzdata"
+version = "2021.5"
+description = "Provider of IANA time zone data"
+category = "main"
+optional = false
+python-versions = ">=2"
+
[[package]]
name = "tzlocal"
-version = "2.1"
+version = "4.1"
description = "tzinfo object for the local timezone"
category = "main"
optional = false
-python-versions = "*"
+python-versions = ">=3.6"
[package.dependencies]
-pytz = "*"
+pytz-deprecation-shim = "*"
+tzdata = {version = "*", markers = "platform_system == \"Windows\""}
+
+[package.extras]
+devenv = ["black", "pyroma", "pytest-cov", "zest.releaser"]
+test = ["pytest-mock (>=3.3)", "pytest (>=4.3)"]
[[package]]
name = "urllib3"
@@ -1370,7 +1394,7 @@ python-versions = ">=3.6.1"
[[package]]
name = "wrapt"
-version = "1.13.2"
+version = "1.13.3"
description = "Module for decorators, wrappers and monkey patching."
category = "dev"
optional = false
@@ -1414,12 +1438,12 @@ apprise = [
{file = "apprise-0.9.3.tar.gz", hash = "sha256:c8ace9c891d4224558570acbea808f31df9049530bd9ccd69901c27a65d600c4"},
]
apscheduler = [
- {file = "APScheduler-3.8.0-py2.py3-none-any.whl", hash = "sha256:82d6d21b2f0343510d07bb35618333a794653439a265635555b12935647b460a"},
- {file = "APScheduler-3.8.0.tar.gz", hash = "sha256:793b2d37c52ece53e34626619e6142e99b20b59a12155f39e1e6932e324f079d"},
+ {file = "APScheduler-3.8.1-py2.py3-none-any.whl", hash = "sha256:c22cb14b411a31435eb2c530dfbbec948ac63015b517087c7978adb61b574865"},
+ {file = "APScheduler-3.8.1.tar.gz", hash = "sha256:5cf344ebcfbdaa48ae178c029c055cec7bc7a4a47c21e315e4d1f08bd35f2355"},
]
astroid = [
- {file = "astroid-2.8.3-py3-none-any.whl", hash = "sha256:f9d66e3a4a0e5b52819b2ff41ac2b179df9d180697db71c92beb33a60c661794"},
- {file = "astroid-2.8.3.tar.gz", hash = "sha256:0e361da0744d5011d4f5d57e64473ba9b7ab4da1e2d45d6631ebd67dd28c3cce"},
+ {file = "astroid-2.8.4-py3-none-any.whl", hash = "sha256:0755c998e7117078dcb7d0bda621391dd2a85da48052d948c7411ab187325346"},
+ {file = "astroid-2.8.4.tar.gz", hash = "sha256:1e83a69fd51b013ebf5912d26b9338d6643a55fec2f20c787792680610eed4a2"},
]
atomicwrites = [
{file = "atomicwrites-1.4.0-py2.py3-none-any.whl", hash = "sha256:6d1784dea7c0c8d4a5172b6c620f40b6e4cbfdf96d783691f2e1302a7b88e197"},
@@ -1820,12 +1844,28 @@ markdown = [
{file = "Markdown-3.3.4.tar.gz", hash = "sha256:31b5b491868dcc87d6c24b7e3d19a0d730d59d3e46f4eea6430a321bed387a49"},
]
markupsafe = [
+ {file = "MarkupSafe-2.0.1-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:d8446c54dc28c01e5a2dbac5a25f071f6653e6e40f3a8818e8b45d790fe6ef53"},
+ {file = "MarkupSafe-2.0.1-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:36bc903cbb393720fad60fc28c10de6acf10dc6cc883f3e24ee4012371399a38"},
+ {file = "MarkupSafe-2.0.1-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:2d7d807855b419fc2ed3e631034685db6079889a1f01d5d9dac950f764da3dad"},
+ {file = "MarkupSafe-2.0.1-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_12_i686.manylinux2010_i686.whl", hash = "sha256:add36cb2dbb8b736611303cd3bfcee00afd96471b09cda130da3581cbdc56a6d"},
+ {file = "MarkupSafe-2.0.1-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:168cd0a3642de83558a5153c8bd34f175a9a6e7f6dc6384b9655d2697312a646"},
+ {file = "MarkupSafe-2.0.1-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:4dc8f9fb58f7364b63fd9f85013b780ef83c11857ae79f2feda41e270468dd9b"},
+ {file = "MarkupSafe-2.0.1-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:20dca64a3ef2d6e4d5d615a3fd418ad3bde77a47ec8a23d984a12b5b4c74491a"},
+ {file = "MarkupSafe-2.0.1-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:cdfba22ea2f0029c9261a4bd07e830a8da012291fbe44dc794e488b6c9bb353a"},
+ {file = "MarkupSafe-2.0.1-cp310-cp310-win32.whl", hash = "sha256:99df47edb6bda1249d3e80fdabb1dab8c08ef3975f69aed437cb69d0a5de1e28"},
+ {file = "MarkupSafe-2.0.1-cp310-cp310-win_amd64.whl", hash = "sha256:e0f138900af21926a02425cf736db95be9f4af72ba1bb21453432a07f6082134"},
{file = "MarkupSafe-2.0.1-cp36-cp36m-macosx_10_9_x86_64.whl", hash = "sha256:f9081981fe268bd86831e5c75f7de206ef275defcb82bc70740ae6dc507aee51"},
{file = "MarkupSafe-2.0.1-cp36-cp36m-manylinux1_i686.whl", hash = "sha256:0955295dd5eec6cb6cc2fe1698f4c6d84af2e92de33fbcac4111913cd100a6ff"},
{file = "MarkupSafe-2.0.1-cp36-cp36m-manylinux1_x86_64.whl", hash = "sha256:0446679737af14f45767963a1a9ef7620189912317d095f2d9ffa183a4d25d2b"},
{file = "MarkupSafe-2.0.1-cp36-cp36m-manylinux2010_i686.whl", hash = "sha256:f826e31d18b516f653fe296d967d700fddad5901ae07c622bb3705955e1faa94"},
{file = "MarkupSafe-2.0.1-cp36-cp36m-manylinux2010_x86_64.whl", hash = "sha256:fa130dd50c57d53368c9d59395cb5526eda596d3ffe36666cd81a44d56e48872"},
{file = "MarkupSafe-2.0.1-cp36-cp36m-manylinux2014_aarch64.whl", hash = "sha256:905fec760bd2fa1388bb5b489ee8ee5f7291d692638ea5f67982d968366bef9f"},
+ {file = "MarkupSafe-2.0.1-cp36-cp36m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:bf5d821ffabf0ef3533c39c518f3357b171a1651c1ff6827325e4489b0e46c3c"},
+ {file = "MarkupSafe-2.0.1-cp36-cp36m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_12_i686.manylinux2010_i686.whl", hash = "sha256:0d4b31cc67ab36e3392bbf3862cfbadac3db12bdd8b02a2731f509ed5b829724"},
+ {file = "MarkupSafe-2.0.1-cp36-cp36m-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:baa1a4e8f868845af802979fcdbf0bb11f94f1cb7ced4c4b8a351bb60d108145"},
+ {file = "MarkupSafe-2.0.1-cp36-cp36m-musllinux_1_1_aarch64.whl", hash = "sha256:deb993cacb280823246a026e3b2d81c493c53de6acfd5e6bfe31ab3402bb37dd"},
+ {file = "MarkupSafe-2.0.1-cp36-cp36m-musllinux_1_1_i686.whl", hash = "sha256:63f3268ba69ace99cab4e3e3b5840b03340efed0948ab8f78d2fd87ee5442a4f"},
+ {file = "MarkupSafe-2.0.1-cp36-cp36m-musllinux_1_1_x86_64.whl", hash = "sha256:8d206346619592c6200148b01a2142798c989edcb9c896f9ac9722a99d4e77e6"},
{file = "MarkupSafe-2.0.1-cp36-cp36m-win32.whl", hash = "sha256:6c4ca60fa24e85fe25b912b01e62cb969d69a23a5d5867682dd3e80b5b02581d"},
{file = "MarkupSafe-2.0.1-cp36-cp36m-win_amd64.whl", hash = "sha256:b2f4bf27480f5e5e8ce285a8c8fd176c0b03e93dcc6646477d4630e83440c6a9"},
{file = "MarkupSafe-2.0.1-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:0717a7390a68be14b8c793ba258e075c6f4ca819f15edfc2a3a027c823718567"},
@@ -1834,14 +1874,27 @@ markupsafe = [
{file = "MarkupSafe-2.0.1-cp37-cp37m-manylinux2010_i686.whl", hash = "sha256:d7f9850398e85aba693bb640262d3611788b1f29a79f0c93c565694658f4071f"},
{file = "MarkupSafe-2.0.1-cp37-cp37m-manylinux2010_x86_64.whl", hash = "sha256:6a7fae0dd14cf60ad5ff42baa2e95727c3d81ded453457771d02b7d2b3f9c0c2"},
{file = "MarkupSafe-2.0.1-cp37-cp37m-manylinux2014_aarch64.whl", hash = "sha256:b7f2d075102dc8c794cbde1947378051c4e5180d52d276987b8d28a3bd58c17d"},
+ {file = "MarkupSafe-2.0.1-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:e9936f0b261d4df76ad22f8fee3ae83b60d7c3e871292cd42f40b81b70afae85"},
+ {file = "MarkupSafe-2.0.1-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_12_i686.manylinux2010_i686.whl", hash = "sha256:2a7d351cbd8cfeb19ca00de495e224dea7e7d919659c2841bbb7f420ad03e2d6"},
+ {file = "MarkupSafe-2.0.1-cp37-cp37m-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:60bf42e36abfaf9aff1f50f52644b336d4f0a3fd6d8a60ca0d054ac9f713a864"},
+ {file = "MarkupSafe-2.0.1-cp37-cp37m-musllinux_1_1_aarch64.whl", hash = "sha256:d6c7ebd4e944c85e2c3421e612a7057a2f48d478d79e61800d81468a8d842207"},
+ {file = "MarkupSafe-2.0.1-cp37-cp37m-musllinux_1_1_i686.whl", hash = "sha256:f0567c4dc99f264f49fe27da5f735f414c4e7e7dd850cfd8e69f0862d7c74ea9"},
+ {file = "MarkupSafe-2.0.1-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:89c687013cb1cd489a0f0ac24febe8c7a666e6e221b783e53ac50ebf68e45d86"},
{file = "MarkupSafe-2.0.1-cp37-cp37m-win32.whl", hash = "sha256:a30e67a65b53ea0a5e62fe23682cfe22712e01f453b95233b25502f7c61cb415"},
{file = "MarkupSafe-2.0.1-cp37-cp37m-win_amd64.whl", hash = "sha256:611d1ad9a4288cf3e3c16014564df047fe08410e628f89805e475368bd304914"},
+ {file = "MarkupSafe-2.0.1-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:5bb28c636d87e840583ee3adeb78172efc47c8b26127267f54a9c0ec251d41a9"},
{file = "MarkupSafe-2.0.1-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:be98f628055368795d818ebf93da628541e10b75b41c559fdf36d104c5787066"},
{file = "MarkupSafe-2.0.1-cp38-cp38-manylinux1_i686.whl", hash = "sha256:1d609f577dc6e1aa17d746f8bd3c31aa4d258f4070d61b2aa5c4166c1539de35"},
{file = "MarkupSafe-2.0.1-cp38-cp38-manylinux1_x86_64.whl", hash = "sha256:7d91275b0245b1da4d4cfa07e0faedd5b0812efc15b702576d103293e252af1b"},
{file = "MarkupSafe-2.0.1-cp38-cp38-manylinux2010_i686.whl", hash = "sha256:01a9b8ea66f1658938f65b93a85ebe8bc016e6769611be228d797c9d998dd298"},
{file = "MarkupSafe-2.0.1-cp38-cp38-manylinux2010_x86_64.whl", hash = "sha256:47ab1e7b91c098ab893b828deafa1203de86d0bc6ab587b160f78fe6c4011f75"},
{file = "MarkupSafe-2.0.1-cp38-cp38-manylinux2014_aarch64.whl", hash = "sha256:97383d78eb34da7e1fa37dd273c20ad4320929af65d156e35a5e2d89566d9dfb"},
+ {file = "MarkupSafe-2.0.1-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:6fcf051089389abe060c9cd7caa212c707e58153afa2c649f00346ce6d260f1b"},
+ {file = "MarkupSafe-2.0.1-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_12_i686.manylinux2010_i686.whl", hash = "sha256:5855f8438a7d1d458206a2466bf82b0f104a3724bf96a1c781ab731e4201731a"},
+ {file = "MarkupSafe-2.0.1-cp38-cp38-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:3dd007d54ee88b46be476e293f48c85048603f5f516008bee124ddd891398ed6"},
+ {file = "MarkupSafe-2.0.1-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:aca6377c0cb8a8253e493c6b451565ac77e98c2951c45f913e0b52facdcff83f"},
+ {file = "MarkupSafe-2.0.1-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:04635854b943835a6ea959e948d19dcd311762c5c0c6e1f0e16ee57022669194"},
+ {file = "MarkupSafe-2.0.1-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:6300b8454aa6930a24b9618fbb54b5a68135092bc666f7b06901f897fa5c2fee"},
{file = "MarkupSafe-2.0.1-cp38-cp38-win32.whl", hash = "sha256:023cb26ec21ece8dc3907c0e8320058b2e0cb3c55cf9564da612bc325bed5e64"},
{file = "MarkupSafe-2.0.1-cp38-cp38-win_amd64.whl", hash = "sha256:984d76483eb32f1bcb536dc27e4ad56bba4baa70be32fa87152832cdd9db0833"},
{file = "MarkupSafe-2.0.1-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:2ef54abee730b502252bcdf31b10dacb0a416229b72c18b19e24a4509f273d26"},
@@ -1851,6 +1904,12 @@ markupsafe = [
{file = "MarkupSafe-2.0.1-cp39-cp39-manylinux2010_i686.whl", hash = "sha256:4efca8f86c54b22348a5467704e3fec767b2db12fc39c6d963168ab1d3fc9135"},
{file = "MarkupSafe-2.0.1-cp39-cp39-manylinux2010_x86_64.whl", hash = "sha256:ab3ef638ace319fa26553db0624c4699e31a28bb2a835c5faca8f8acf6a5a902"},
{file = "MarkupSafe-2.0.1-cp39-cp39-manylinux2014_aarch64.whl", hash = "sha256:f8ba0e8349a38d3001fae7eadded3f6606f0da5d748ee53cc1dab1d6527b9509"},
+ {file = "MarkupSafe-2.0.1-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c47adbc92fc1bb2b3274c4b3a43ae0e4573d9fbff4f54cd484555edbf030baf1"},
+ {file = "MarkupSafe-2.0.1-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_12_i686.manylinux2010_i686.whl", hash = "sha256:37205cac2a79194e3750b0af2a5720d95f786a55ce7df90c3af697bfa100eaac"},
+ {file = "MarkupSafe-2.0.1-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:1f2ade76b9903f39aa442b4aadd2177decb66525062db244b35d71d0ee8599b6"},
+ {file = "MarkupSafe-2.0.1-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:4296f2b1ce8c86a6aea78613c34bb1a672ea0e3de9c6ba08a960efe0b0a09047"},
+ {file = "MarkupSafe-2.0.1-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:9f02365d4e99430a12647f09b6cc8bab61a6564363f313126f775eb4f6ef798e"},
+ {file = "MarkupSafe-2.0.1-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:5b6d930f030f8ed98e3e6c98ffa0652bdb82601e7a016ec2ab5d7ff23baa78d1"},
{file = "MarkupSafe-2.0.1-cp39-cp39-win32.whl", hash = "sha256:10f82115e21dc0dfec9ab5c0223652f7197feb168c940f3ef61563fc2d6beb74"},
{file = "MarkupSafe-2.0.1-cp39-cp39-win_amd64.whl", hash = "sha256:693ce3f9e70a6cf7d2fb9e6c9d8b204b6b39897a2c4a1aa65728d5ac97dcc1d8"},
{file = "MarkupSafe-2.0.1.tar.gz", hash = "sha256:594c67807fb16238b30c44bdf74f36c02cdf22d1c8cda91ef8a0ed8dabf5620a"},
@@ -1871,8 +1930,8 @@ mkdocs = [
{file = "mkdocs-1.2.3.tar.gz", hash = "sha256:89f5a094764381cda656af4298727c9f53dc3e602983087e1fe96ea1df24f4c1"},
]
mkdocs-material = [
- {file = "mkdocs-material-7.3.4.tar.gz", hash = "sha256:9cc0ea54933322792855150ffb89401ff4eaf7737aadca5155fa679195ad803a"},
- {file = "mkdocs_material-7.3.4-py2.py3-none-any.whl", hash = "sha256:6a9c5a2f18a39ac0b6af73d23c452cdb1f9a07bf6365d43ee54cb796b1d2c7eb"},
+ {file = "mkdocs-material-7.3.6.tar.gz", hash = "sha256:1b1dbd8ef2508b358d93af55a5c5db3f141c95667fad802301ec621c40c7c217"},
+ {file = "mkdocs_material-7.3.6-py2.py3-none-any.whl", hash = "sha256:1b6b3e9e09f922c2d7f1160fe15c8f43d4adc0d6fb81aa6ff0cbc7ef5b78ec75"},
]
mkdocs-material-extensions = [
{file = "mkdocs-material-extensions-1.0.3.tar.gz", hash = "sha256:bfd24dfdef7b41c312ede42648f9eb83476ea168ec163b613f9abd12bbfddba2"},
@@ -1887,8 +1946,8 @@ oauthlib = [
{file = "oauthlib-3.1.1.tar.gz", hash = "sha256:8f0215fcc533dd8dd1bee6f4c412d4f0cd7297307d43ac61666389e3bc3198a3"},
]
packaging = [
- {file = "packaging-21.0-py3-none-any.whl", hash = "sha256:c86254f9220d55e31cc94d69bade760f0847da8000def4dfe1c6b872fd14ff14"},
- {file = "packaging-21.0.tar.gz", hash = "sha256:7dc96269f53a4ccec5c0670940a4281106dd0bb343f47b7471f779df49c2fbe7"},
+ {file = "packaging-21.2-py3-none-any.whl", hash = "sha256:14317396d1e8cdb122989b916fa2c7e9ca8e2be9e8060a6eff75b6b7b4d8a7e0"},
+ {file = "packaging-21.2.tar.gz", hash = "sha256:096d689d78ca690e4cd8a89568ba06d07ca097e3306a4381635073ca91479966"},
]
passlib = [
{file = "passlib-1.7.4-py2.py3-none-any.whl", hash = "sha256:aa6bca462b8d8bda89c70b382f0c298a20b5560af6cbfa2dce410c0a2fb669f1"},
@@ -1959,6 +2018,11 @@ premailer = [
]
psycopg2-binary = [
{file = "psycopg2-binary-2.9.1.tar.gz", hash = "sha256:b0221ca5a9837e040ebf61f48899926b5783668b7807419e4adae8175a31f773"},
+ {file = "psycopg2_binary-2.9.1-cp310-cp310-macosx_10_14_x86_64.macosx_10_9_intel.macosx_10_9_x86_64.macosx_10_10_intel.macosx_10_10_x86_64.whl", hash = "sha256:24b0b6688b9f31a911f2361fe818492650795c9e5d3a1bc647acbd7440142a4f"},
+ {file = "psycopg2_binary-2.9.1-cp310-cp310-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:542875f62bc56e91c6eac05a0deadeae20e1730be4c6334d8f04c944fcd99759"},
+ {file = "psycopg2_binary-2.9.1-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:661509f51531ec125e52357a489ea3806640d0ca37d9dada461ffc69ee1e7b6e"},
+ {file = "psycopg2_binary-2.9.1-cp310-cp310-manylinux_2_24_aarch64.whl", hash = "sha256:d92272c7c16e105788efe2cfa5d680f07e34e0c29b03c1908f8636f55d5f915a"},
+ {file = "psycopg2_binary-2.9.1-cp310-cp310-manylinux_2_24_ppc64le.whl", hash = "sha256:736b8797b58febabb85494142c627bd182b50d2a7ec65322983e71065ad3034c"},
{file = "psycopg2_binary-2.9.1-cp36-cp36m-macosx_10_14_x86_64.macosx_10_9_intel.macosx_10_9_x86_64.macosx_10_10_intel.macosx_10_10_x86_64.whl", hash = "sha256:c250a7ec489b652c892e4f0a5d122cc14c3780f9f643e1a326754aedf82d9a76"},
{file = "psycopg2_binary-2.9.1-cp36-cp36m-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:aef9aee84ec78af51107181d02fe8773b100b01c5dfde351184ad9223eab3698"},
{file = "psycopg2_binary-2.9.1-cp36-cp36m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:123c3fb684e9abfc47218d3784c7b4c47c8587951ea4dd5bc38b6636ac57f616"},
@@ -2106,6 +2170,10 @@ pytz = [
{file = "pytz-2021.3-py2.py3-none-any.whl", hash = "sha256:3672058bc3453457b622aab7a1c3bfd5ab0bdae451512f6cf25f64ed37f5b87c"},
{file = "pytz-2021.3.tar.gz", hash = "sha256:acad2d8b20a1af07d4e4c9d2e9285c5ed9104354062f275f3fcd88dcef4f1326"},
]
+pytz-deprecation-shim = [
+ {file = "pytz_deprecation_shim-0.1.0.post0-py2.py3-none-any.whl", hash = "sha256:8314c9692a636c8eb3bda879b9f119e350e93223ae83e70e80c31675a0fdc1a6"},
+ {file = "pytz_deprecation_shim-0.1.0.post0.tar.gz", hash = "sha256:af097bae1b616dde5c5744441e2ddc69e74dfdcb0c263129610d85b87445a59d"},
+]
pyyaml = [
{file = "PyYAML-5.4.1-cp27-cp27m-macosx_10_9_x86_64.whl", hash = "sha256:3b2b1824fe7112845700f815ff6a489360226a5609b96ec2190a45e62a9fc922"},
{file = "PyYAML-5.4.1-cp27-cp27m-win32.whl", hash = "sha256:129def1b7c1bf22faffd67b8f3724645203b79d8f4cc81f674654d9902cb4393"},
@@ -2113,18 +2181,26 @@ pyyaml = [
{file = "PyYAML-5.4.1-cp27-cp27mu-manylinux1_x86_64.whl", hash = "sha256:bb4191dfc9306777bc594117aee052446b3fa88737cd13b7188d0e7aa8162185"},
{file = "PyYAML-5.4.1-cp36-cp36m-macosx_10_9_x86_64.whl", hash = "sha256:6c78645d400265a062508ae399b60b8c167bf003db364ecb26dcab2bda048253"},
{file = "PyYAML-5.4.1-cp36-cp36m-manylinux1_x86_64.whl", hash = "sha256:4e0583d24c881e14342eaf4ec5fbc97f934b999a6828693a99157fde912540cc"},
+ {file = "PyYAML-5.4.1-cp36-cp36m-manylinux2014_aarch64.whl", hash = "sha256:72a01f726a9c7851ca9bfad6fd09ca4e090a023c00945ea05ba1638c09dc3347"},
+ {file = "PyYAML-5.4.1-cp36-cp36m-manylinux2014_s390x.whl", hash = "sha256:895f61ef02e8fed38159bb70f7e100e00f471eae2bc838cd0f4ebb21e28f8541"},
{file = "PyYAML-5.4.1-cp36-cp36m-win32.whl", hash = "sha256:3bd0e463264cf257d1ffd2e40223b197271046d09dadf73a0fe82b9c1fc385a5"},
{file = "PyYAML-5.4.1-cp36-cp36m-win_amd64.whl", hash = "sha256:e4fac90784481d221a8e4b1162afa7c47ed953be40d31ab4629ae917510051df"},
{file = "PyYAML-5.4.1-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:5accb17103e43963b80e6f837831f38d314a0495500067cb25afab2e8d7a4018"},
{file = "PyYAML-5.4.1-cp37-cp37m-manylinux1_x86_64.whl", hash = "sha256:e1d4970ea66be07ae37a3c2e48b5ec63f7ba6804bdddfdbd3cfd954d25a82e63"},
+ {file = "PyYAML-5.4.1-cp37-cp37m-manylinux2014_aarch64.whl", hash = "sha256:cb333c16912324fd5f769fff6bc5de372e9e7a202247b48870bc251ed40239aa"},
+ {file = "PyYAML-5.4.1-cp37-cp37m-manylinux2014_s390x.whl", hash = "sha256:fe69978f3f768926cfa37b867e3843918e012cf83f680806599ddce33c2c68b0"},
{file = "PyYAML-5.4.1-cp37-cp37m-win32.whl", hash = "sha256:dd5de0646207f053eb0d6c74ae45ba98c3395a571a2891858e87df7c9b9bd51b"},
{file = "PyYAML-5.4.1-cp37-cp37m-win_amd64.whl", hash = "sha256:08682f6b72c722394747bddaf0aa62277e02557c0fd1c42cb853016a38f8dedf"},
{file = "PyYAML-5.4.1-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:d2d9808ea7b4af864f35ea216be506ecec180628aced0704e34aca0b040ffe46"},
{file = "PyYAML-5.4.1-cp38-cp38-manylinux1_x86_64.whl", hash = "sha256:8c1be557ee92a20f184922c7b6424e8ab6691788e6d86137c5d93c1a6ec1b8fb"},
+ {file = "PyYAML-5.4.1-cp38-cp38-manylinux2014_aarch64.whl", hash = "sha256:fd7f6999a8070df521b6384004ef42833b9bd62cfee11a09bda1079b4b704247"},
+ {file = "PyYAML-5.4.1-cp38-cp38-manylinux2014_s390x.whl", hash = "sha256:bfb51918d4ff3d77c1c856a9699f8492c612cde32fd3bcd344af9be34999bfdc"},
{file = "PyYAML-5.4.1-cp38-cp38-win32.whl", hash = "sha256:fa5ae20527d8e831e8230cbffd9f8fe952815b2b7dae6ffec25318803a7528fc"},
{file = "PyYAML-5.4.1-cp38-cp38-win_amd64.whl", hash = "sha256:0f5f5786c0e09baddcd8b4b45f20a7b5d61a7e7e99846e3c799b05c7c53fa696"},
{file = "PyYAML-5.4.1-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:294db365efa064d00b8d1ef65d8ea2c3426ac366c0c4368d930bf1c5fb497f77"},
{file = "PyYAML-5.4.1-cp39-cp39-manylinux1_x86_64.whl", hash = "sha256:74c1485f7707cf707a7aef42ef6322b8f97921bd89be2ab6317fd782c2d53183"},
+ {file = "PyYAML-5.4.1-cp39-cp39-manylinux2014_aarch64.whl", hash = "sha256:d483ad4e639292c90170eb6f7783ad19490e7a8defb3e46f97dfe4bacae89122"},
+ {file = "PyYAML-5.4.1-cp39-cp39-manylinux2014_s390x.whl", hash = "sha256:fdc842473cd33f45ff6bce46aea678a54e3d21f1b61a7750ce3c498eedfe25d6"},
{file = "PyYAML-5.4.1-cp39-cp39-win32.whl", hash = "sha256:49d4cdd9065b9b6e206d0595fee27a96b5dd22618e7520c33204a4a3239d5b10"},
{file = "PyYAML-5.4.1-cp39-cp39-win_amd64.whl", hash = "sha256:c20cfa2d49991c8b4147af39859b167664f2ad4561704ee74c1de03318e898db"},
{file = "PyYAML-5.4.1.tar.gz", hash = "sha256:607774cbba28732bfa802b54baa7484215f530991055bb562efbed5b2f20a45e"},
@@ -2221,6 +2297,8 @@ sqlalchemy = [
{file = "SQLAlchemy-1.4.26-cp27-cp27mu-manylinux_2_5_x86_64.manylinux1_x86_64.whl", hash = "sha256:c757ba1279b85b3460e72e8b92239dae6f8b060a75fb24b3d9be984dd78cfa55"},
{file = "SQLAlchemy-1.4.26-cp310-cp310-macosx_10_14_x86_64.whl", hash = "sha256:c24c01dcd03426a5fe5ee7af735906bec6084977b9027a3605d11d949a565c01"},
{file = "SQLAlchemy-1.4.26-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c46f013ff31b80cbe36410281675e1fb4eaf3e25c284fd8a69981c73f6fa4cb4"},
+ {file = "SQLAlchemy-1.4.26-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:fb2aa74a6e3c2cebea38dd21633671841fbe70ea486053cba33d68e3e22ccc0a"},
+ {file = "SQLAlchemy-1.4.26-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ad7e403fc1e3cb76e802872694e30d6ca6129b9bc6ad4e7caa48ca35f8a144f8"},
{file = "SQLAlchemy-1.4.26-cp310-cp310-win32.whl", hash = "sha256:7ef421c3887b39c6f352e5022a53ac18de8387de331130481cb956b2d029cad6"},
{file = "SQLAlchemy-1.4.26-cp310-cp310-win_amd64.whl", hash = "sha256:908fad32c53b17aad12d722379150c3c5317c422437e44032256a77df1746292"},
{file = "SQLAlchemy-1.4.26-cp36-cp36m-macosx_10_14_x86_64.whl", hash = "sha256:1ef37c9ec2015ce2f0dc1084514e197f2f199d3dc3514190db7620b78e6004c8"},
@@ -2298,9 +2376,13 @@ typing-extensions = [
{file = "typing_extensions-3.10.0.2-py3-none-any.whl", hash = "sha256:f1d25edafde516b146ecd0613dabcc61409817af4766fbbcfb8d1ad4ec441a34"},
{file = "typing_extensions-3.10.0.2.tar.gz", hash = "sha256:49f75d16ff11f1cd258e1b988ccff82a3ca5570217d7ad8c5f48205dd99a677e"},
]
+tzdata = [
+ {file = "tzdata-2021.5-py2.py3-none-any.whl", hash = "sha256:3eee491e22ebfe1e5cfcc97a4137cd70f092ce59144d81f8924a844de05ba8f5"},
+ {file = "tzdata-2021.5.tar.gz", hash = "sha256:68dbe41afd01b867894bbdfd54fa03f468cfa4f0086bfb4adcd8de8f24f3ee21"},
+]
tzlocal = [
- {file = "tzlocal-2.1-py2.py3-none-any.whl", hash = "sha256:e2cb6c6b5b604af38597403e9852872d7f534962ae2954c7f35efcb1ccacf4a4"},
- {file = "tzlocal-2.1.tar.gz", hash = "sha256:643c97c5294aedc737780a49d9df30889321cbe1204eac2c2ec6134035a92e44"},
+ {file = "tzlocal-4.1-py3-none-any.whl", hash = "sha256:28ba8d9fcb6c9a782d6e0078b4f6627af1ea26aeaa32b4eab5324abc7df4149f"},
+ {file = "tzlocal-4.1.tar.gz", hash = "sha256:0f28015ac68a5c067210400a9197fc5d36ba9bc3f8eaf1da3cbd59acdfed9e09"},
]
urllib3 = [
{file = "urllib3-1.26.7-py2.py3-none-any.whl", hash = "sha256:c4fdf4019605b6e5423637e01bc9fe4daef873709a7973e195ceba0a62bbc844"},
@@ -2390,50 +2472,57 @@ websockets = [
{file = "websockets-8.1.tar.gz", hash = "sha256:5c65d2da8c6bce0fca2528f69f44b2f977e06954c8512a952222cea50dad430f"},
]
wrapt = [
- {file = "wrapt-1.13.2-cp27-cp27m-macosx_10_9_x86_64.whl", hash = "sha256:3de7b4d3066cc610054e7aa2c005645e308df2f92be730aae3a47d42e910566a"},
- {file = "wrapt-1.13.2-cp27-cp27m-manylinux1_i686.whl", hash = "sha256:8164069f775c698d15582bf6320a4f308c50d048c1c10cf7d7a341feaccf5df7"},
- {file = "wrapt-1.13.2-cp27-cp27m-manylinux1_x86_64.whl", hash = "sha256:9adee1891253670575028279de8365c3a02d3489a74a66d774c321472939a0b1"},
- {file = "wrapt-1.13.2-cp27-cp27m-manylinux2010_i686.whl", hash = "sha256:a70d876c9aba12d3bd7f8f1b05b419322c6789beb717044eea2c8690d35cb91b"},
- {file = "wrapt-1.13.2-cp27-cp27m-manylinux2010_x86_64.whl", hash = "sha256:3f87042623530bcffea038f824b63084180513c21e2e977291a9a7e65a66f13b"},
- {file = "wrapt-1.13.2-cp27-cp27mu-manylinux1_i686.whl", hash = "sha256:e634136f700a21e1fcead0c137f433dde928979538c14907640607d43537d468"},
- {file = "wrapt-1.13.2-cp27-cp27mu-manylinux1_x86_64.whl", hash = "sha256:3e33c138d1e3620b1e0cc6fd21e46c266393ed5dae0d595b7ed5a6b73ed57aa0"},
- {file = "wrapt-1.13.2-cp27-cp27mu-manylinux2010_i686.whl", hash = "sha256:283e402e5357e104ac1e3fba5791220648e9af6fb14ad7d9cc059091af2b31d2"},
- {file = "wrapt-1.13.2-cp27-cp27mu-manylinux2010_x86_64.whl", hash = "sha256:ccb34ce599cab7f36a4c90318697ead18312c67a9a76327b3f4f902af8f68ea1"},
- {file = "wrapt-1.13.2-cp35-cp35m-manylinux1_i686.whl", hash = "sha256:fbad5ba74c46517e6488149514b2e2348d40df88cd6b52a83855b7a8bf04723f"},
- {file = "wrapt-1.13.2-cp35-cp35m-manylinux1_x86_64.whl", hash = "sha256:724ed2bc9c91a2b9026e5adce310fa60c6e7c8760b03391445730b9789b9d108"},
- {file = "wrapt-1.13.2-cp35-cp35m-manylinux2010_i686.whl", hash = "sha256:83f2793ec6f3ef513ad8d5b9586f5ee6081cad132e6eae2ecb7eac1cc3decae0"},
- {file = "wrapt-1.13.2-cp35-cp35m-manylinux2010_x86_64.whl", hash = "sha256:0473d1558b93e314e84313cc611f6c86be779369f9d3734302bf185a4d2625b1"},
- {file = "wrapt-1.13.2-cp35-cp35m-win32.whl", hash = "sha256:15eee0e6fd07f48af2f66d0e6f2ff1916ffe9732d464d5e2390695296872cad9"},
- {file = "wrapt-1.13.2-cp35-cp35m-win_amd64.whl", hash = "sha256:bc85d17d90201afd88e3d25421da805e4e135012b5d1f149e4de2981394b2a52"},
- {file = "wrapt-1.13.2-cp36-cp36m-macosx_10_9_x86_64.whl", hash = "sha256:c6ee5f8734820c21b9b8bf705e99faba87f21566d20626568eeb0d62cbeaf23c"},
- {file = "wrapt-1.13.2-cp36-cp36m-manylinux1_i686.whl", hash = "sha256:53c6706a1bcfb6436f1625511b95b812798a6d2ccc51359cd791e33722b5ea32"},
- {file = "wrapt-1.13.2-cp36-cp36m-manylinux1_x86_64.whl", hash = "sha256:fbe6aebc9559fed7ea27de51c2bf5c25ba2a4156cf0017556f72883f2496ee9a"},
- {file = "wrapt-1.13.2-cp36-cp36m-manylinux2010_i686.whl", hash = "sha256:0582180566e7a13030f896c2f1ac6a56134ab5f3c3f4c5538086f758b1caf3f2"},
- {file = "wrapt-1.13.2-cp36-cp36m-manylinux2010_x86_64.whl", hash = "sha256:bff0a59387a0a2951cb869251257b6553663329a1b5525b5226cab8c88dcbe7e"},
- {file = "wrapt-1.13.2-cp36-cp36m-win32.whl", hash = "sha256:df3eae297a5f1594d1feb790338120f717dac1fa7d6feed7b411f87e0f2401c7"},
- {file = "wrapt-1.13.2-cp36-cp36m-win_amd64.whl", hash = "sha256:1eb657ed84f4d3e6ad648483c8a80a0cf0a78922ef94caa87d327e2e1ad49b48"},
- {file = "wrapt-1.13.2-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:a0cdedf681db878416c05e1831ec69691b0e6577ac7dca9d4f815632e3549580"},
- {file = "wrapt-1.13.2-cp37-cp37m-manylinux1_i686.whl", hash = "sha256:87ee3c73bdfb4367b26c57259995935501829f00c7b3eed373e2ad19ec21e4e4"},
- {file = "wrapt-1.13.2-cp37-cp37m-manylinux1_x86_64.whl", hash = "sha256:3e0d16eedc242d01a6f8cf0623e9cdc3b869329da3f97a15961d8864111d8cf0"},
- {file = "wrapt-1.13.2-cp37-cp37m-manylinux2010_i686.whl", hash = "sha256:8318088860968c07e741537030b1abdd8908ee2c71fbe4facdaade624a09e006"},
- {file = "wrapt-1.13.2-cp37-cp37m-manylinux2010_x86_64.whl", hash = "sha256:d90520616fce71c05dedeac3a0fe9991605f0acacd276e5f821842e454485a70"},
- {file = "wrapt-1.13.2-cp37-cp37m-win32.whl", hash = "sha256:22142afab65daffc95863d78effcbd31c19a8003eca73de59f321ee77f73cadb"},
- {file = "wrapt-1.13.2-cp37-cp37m-win_amd64.whl", hash = "sha256:d0d717e10f952df7ea41200c507cc7e24458f4c45b56c36ad418d2e79dacd1d4"},
- {file = "wrapt-1.13.2-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:593cb049ce1c391e0288523b30426c4430b26e74c7e6f6e2844bd99ac7ecc831"},
- {file = "wrapt-1.13.2-cp38-cp38-manylinux1_i686.whl", hash = "sha256:8860c8011a6961a651b1b9f46fdbc589ab63b0a50d645f7d92659618a3655867"},
- {file = "wrapt-1.13.2-cp38-cp38-manylinux1_x86_64.whl", hash = "sha256:ada5e29e59e2feb710589ca1c79fd989b1dd94d27079dc1d199ec954a6ecc724"},
- {file = "wrapt-1.13.2-cp38-cp38-manylinux2010_i686.whl", hash = "sha256:fdede980273aeca591ad354608778365a3a310e0ecdd7a3587b38bc5be9b1808"},
- {file = "wrapt-1.13.2-cp38-cp38-manylinux2010_x86_64.whl", hash = "sha256:af9480de8e63c5f959a092047aaf3d7077422ded84695b3398f5d49254af3e90"},
- {file = "wrapt-1.13.2-cp38-cp38-win32.whl", hash = "sha256:c65e623ea7556e39c4f0818200a046cbba7575a6b570ff36122c276fdd30ab0a"},
- {file = "wrapt-1.13.2-cp38-cp38-win_amd64.whl", hash = "sha256:b20703356cae1799080d0ad15085dc3213c1ac3f45e95afb9f12769b98231528"},
- {file = "wrapt-1.13.2-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:1c5c4cf188b5643a97e87e2110bbd4f5bc491d54a5b90633837b34d5df6a03fe"},
- {file = "wrapt-1.13.2-cp39-cp39-manylinux1_i686.whl", hash = "sha256:82223f72eba6f63eafca87a0f614495ae5aa0126fe54947e2b8c023969e9f2d7"},
- {file = "wrapt-1.13.2-cp39-cp39-manylinux1_x86_64.whl", hash = "sha256:81a4cf257263b299263472d669692785f9c647e7dca01c18286b8f116dbf6b38"},
- {file = "wrapt-1.13.2-cp39-cp39-manylinux2010_i686.whl", hash = "sha256:728e2d9b7a99dd955d3426f237b940fc74017c4a39b125fec913f575619ddfe9"},
- {file = "wrapt-1.13.2-cp39-cp39-manylinux2010_x86_64.whl", hash = "sha256:7574de567dcd4858a2ffdf403088d6df8738b0e1eabea220553abf7c9048f59e"},
- {file = "wrapt-1.13.2-cp39-cp39-win32.whl", hash = "sha256:c7ac2c7a8e34bd06710605b21dd1f3576764443d68e069d2afba9b116014d072"},
- {file = "wrapt-1.13.2-cp39-cp39-win_amd64.whl", hash = "sha256:6e6d1a8eeef415d7fb29fe017de0e48f45e45efd2d1bfda28fc50b7b330859ef"},
- {file = "wrapt-1.13.2.tar.gz", hash = "sha256:dca56cc5963a5fd7c2aa8607017753f534ee514e09103a6c55d2db70b50e7447"},
+ {file = "wrapt-1.13.3-cp27-cp27m-macosx_10_9_x86_64.whl", hash = "sha256:e05e60ff3b2b0342153be4d1b597bbcfd8330890056b9619f4ad6b8d5c96a81a"},
+ {file = "wrapt-1.13.3-cp27-cp27m-manylinux1_i686.whl", hash = "sha256:85148f4225287b6a0665eef08a178c15097366d46b210574a658c1ff5b377489"},
+ {file = "wrapt-1.13.3-cp27-cp27m-manylinux1_x86_64.whl", hash = "sha256:2dded5496e8f1592ec27079b28b6ad2a1ef0b9296d270f77b8e4a3a796cf6909"},
+ {file = "wrapt-1.13.3-cp27-cp27m-manylinux2010_i686.whl", hash = "sha256:e94b7d9deaa4cc7bac9198a58a7240aaf87fe56c6277ee25fa5b3aa1edebd229"},
+ {file = "wrapt-1.13.3-cp27-cp27m-manylinux2010_x86_64.whl", hash = "sha256:498e6217523111d07cd67e87a791f5e9ee769f9241fcf8a379696e25806965af"},
+ {file = "wrapt-1.13.3-cp27-cp27mu-manylinux1_i686.whl", hash = "sha256:ec7e20258ecc5174029a0f391e1b948bf2906cd64c198a9b8b281b811cbc04de"},
+ {file = "wrapt-1.13.3-cp27-cp27mu-manylinux1_x86_64.whl", hash = "sha256:87883690cae293541e08ba2da22cacaae0a092e0ed56bbba8d018cc486fbafbb"},
+ {file = "wrapt-1.13.3-cp27-cp27mu-manylinux2010_i686.whl", hash = "sha256:f99c0489258086308aad4ae57da9e8ecf9e1f3f30fa35d5e170b4d4896554d80"},
+ {file = "wrapt-1.13.3-cp27-cp27mu-manylinux2010_x86_64.whl", hash = "sha256:6a03d9917aee887690aa3f1747ce634e610f6db6f6b332b35c2dd89412912bca"},
+ {file = "wrapt-1.13.3-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:936503cb0a6ed28dbfa87e8fcd0a56458822144e9d11a49ccee6d9a8adb2ac44"},
+ {file = "wrapt-1.13.3-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_12_i686.manylinux2010_i686.whl", hash = "sha256:f9c51d9af9abb899bd34ace878fbec8bf357b3194a10c4e8e0a25512826ef056"},
+ {file = "wrapt-1.13.3-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:220a869982ea9023e163ba915077816ca439489de6d2c09089b219f4e11b6785"},
+ {file = "wrapt-1.13.3-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:0877fe981fd76b183711d767500e6b3111378ed2043c145e21816ee589d91096"},
+ {file = "wrapt-1.13.3-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:43e69ffe47e3609a6aec0fe723001c60c65305784d964f5007d5b4fb1bc6bf33"},
+ {file = "wrapt-1.13.3-cp310-cp310-win32.whl", hash = "sha256:78dea98c81915bbf510eb6a3c9c24915e4660302937b9ae05a0947164248020f"},
+ {file = "wrapt-1.13.3-cp310-cp310-win_amd64.whl", hash = "sha256:ea3e746e29d4000cd98d572f3ee2a6050a4f784bb536f4ac1f035987fc1ed83e"},
+ {file = "wrapt-1.13.3-cp35-cp35m-manylinux1_i686.whl", hash = "sha256:8c73c1a2ec7c98d7eaded149f6d225a692caa1bd7b2401a14125446e9e90410d"},
+ {file = "wrapt-1.13.3-cp35-cp35m-manylinux1_x86_64.whl", hash = "sha256:086218a72ec7d986a3eddb7707c8c4526d677c7b35e355875a0fe2918b059179"},
+ {file = "wrapt-1.13.3-cp35-cp35m-manylinux2010_i686.whl", hash = "sha256:e92d0d4fa68ea0c02d39f1e2f9cb5bc4b4a71e8c442207433d8db47ee79d7aa3"},
+ {file = "wrapt-1.13.3-cp35-cp35m-manylinux2010_x86_64.whl", hash = "sha256:d4a5f6146cfa5c7ba0134249665acd322a70d1ea61732723c7d3e8cc0fa80755"},
+ {file = "wrapt-1.13.3-cp35-cp35m-win32.whl", hash = "sha256:8aab36778fa9bba1a8f06a4919556f9f8c7b33102bd71b3ab307bb3fecb21851"},
+ {file = "wrapt-1.13.3-cp35-cp35m-win_amd64.whl", hash = "sha256:944b180f61f5e36c0634d3202ba8509b986b5fbaf57db3e94df11abee244ba13"},
+ {file = "wrapt-1.13.3-cp36-cp36m-macosx_10_9_x86_64.whl", hash = "sha256:2ebdde19cd3c8cdf8df3fc165bc7827334bc4e353465048b36f7deeae8ee0918"},
+ {file = "wrapt-1.13.3-cp36-cp36m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_12_i686.manylinux2010_i686.whl", hash = "sha256:610f5f83dd1e0ad40254c306f4764fcdc846641f120c3cf424ff57a19d5f7ade"},
+ {file = "wrapt-1.13.3-cp36-cp36m-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:5601f44a0f38fed36cc07db004f0eedeaadbdcec90e4e90509480e7e6060a5bc"},
+ {file = "wrapt-1.13.3-cp36-cp36m-musllinux_1_1_i686.whl", hash = "sha256:e6906d6f48437dfd80464f7d7af1740eadc572b9f7a4301e7dd3d65db285cacf"},
+ {file = "wrapt-1.13.3-cp36-cp36m-musllinux_1_1_x86_64.whl", hash = "sha256:766b32c762e07e26f50d8a3468e3b4228b3736c805018e4b0ec8cc01ecd88125"},
+ {file = "wrapt-1.13.3-cp36-cp36m-win32.whl", hash = "sha256:5f223101f21cfd41deec8ce3889dc59f88a59b409db028c469c9b20cfeefbe36"},
+ {file = "wrapt-1.13.3-cp36-cp36m-win_amd64.whl", hash = "sha256:f122ccd12fdc69628786d0c947bdd9cb2733be8f800d88b5a37c57f1f1d73c10"},
+ {file = "wrapt-1.13.3-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:46f7f3af321a573fc0c3586612db4decb7eb37172af1bc6173d81f5b66c2e068"},
+ {file = "wrapt-1.13.3-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_12_i686.manylinux2010_i686.whl", hash = "sha256:778fd096ee96890c10ce96187c76b3e99b2da44e08c9e24d5652f356873f6709"},
+ {file = "wrapt-1.13.3-cp37-cp37m-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:0cb23d36ed03bf46b894cfec777eec754146d68429c30431c99ef28482b5c1df"},
+ {file = "wrapt-1.13.3-cp37-cp37m-musllinux_1_1_i686.whl", hash = "sha256:96b81ae75591a795d8c90edc0bfaab44d3d41ffc1aae4d994c5aa21d9b8e19a2"},
+ {file = "wrapt-1.13.3-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:7dd215e4e8514004c8d810a73e342c536547038fb130205ec4bba9f5de35d45b"},
+ {file = "wrapt-1.13.3-cp37-cp37m-win32.whl", hash = "sha256:47f0a183743e7f71f29e4e21574ad3fa95676136f45b91afcf83f6a050914829"},
+ {file = "wrapt-1.13.3-cp37-cp37m-win_amd64.whl", hash = "sha256:fd76c47f20984b43d93de9a82011bb6e5f8325df6c9ed4d8310029a55fa361ea"},
+ {file = "wrapt-1.13.3-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:b73d4b78807bd299b38e4598b8e7bd34ed55d480160d2e7fdaabd9931afa65f9"},
+ {file = "wrapt-1.13.3-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_12_i686.manylinux2010_i686.whl", hash = "sha256:ec9465dd69d5657b5d2fa6133b3e1e989ae27d29471a672416fd729b429eb554"},
+ {file = "wrapt-1.13.3-cp38-cp38-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:dd91006848eb55af2159375134d724032a2d1d13bcc6f81cd8d3ed9f2b8e846c"},
+ {file = "wrapt-1.13.3-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:ae9de71eb60940e58207f8e71fe113c639da42adb02fb2bcbcaccc1ccecd092b"},
+ {file = "wrapt-1.13.3-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:51799ca950cfee9396a87f4a1240622ac38973b6df5ef7a41e7f0b98797099ce"},
+ {file = "wrapt-1.13.3-cp38-cp38-win32.whl", hash = "sha256:4b9c458732450ec42578b5642ac53e312092acf8c0bfce140ada5ca1ac556f79"},
+ {file = "wrapt-1.13.3-cp38-cp38-win_amd64.whl", hash = "sha256:7dde79d007cd6dfa65afe404766057c2409316135cb892be4b1c768e3f3a11cb"},
+ {file = "wrapt-1.13.3-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:981da26722bebb9247a0601e2922cedf8bb7a600e89c852d063313102de6f2cb"},
+ {file = "wrapt-1.13.3-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_12_i686.manylinux2010_i686.whl", hash = "sha256:705e2af1f7be4707e49ced9153f8d72131090e52be9278b5dbb1498c749a1e32"},
+ {file = "wrapt-1.13.3-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:25b1b1d5df495d82be1c9d2fad408f7ce5ca8a38085e2da41bb63c914baadff7"},
+ {file = "wrapt-1.13.3-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:77416e6b17926d953b5c666a3cb718d5945df63ecf922af0ee576206d7033b5e"},
+ {file = "wrapt-1.13.3-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:865c0b50003616f05858b22174c40ffc27a38e67359fa1495605f96125f76640"},
+ {file = "wrapt-1.13.3-cp39-cp39-win32.whl", hash = "sha256:0a017a667d1f7411816e4bf214646d0ad5b1da2c1ea13dec6c162736ff25a374"},
+ {file = "wrapt-1.13.3-cp39-cp39-win_amd64.whl", hash = "sha256:81bd7c90d28a4b2e1df135bfbd7c23aee3050078ca6441bead44c42483f9ebfb"},
+ {file = "wrapt-1.13.3.tar.gz", hash = "sha256:1fea9cd438686e6682271d36f3481a9f3636195578bab9ca3382e2f5f01fc185"},
]
zipp = [
{file = "zipp-3.6.0-py3-none-any.whl", hash = "sha256:9fe5ea21568a0a70e50f273397638d39b03353731e6cbbb3fd8502a33fec40bc"},
diff --git a/tests/integration_tests/test_settings_routes.py b/tests/integration_tests/test_settings_routes.py
deleted file mode 100644
index f245c82729d5..000000000000
--- a/tests/integration_tests/test_settings_routes.py
+++ /dev/null
@@ -1,32 +0,0 @@
-import json
-
-import pytest
-from fastapi.testclient import TestClient
-
-from mealie.schema.admin import SiteSettings
-from tests.app_routes import AppRoutes
-
-
-@pytest.fixture(scope="function")
-def default_settings():
- return SiteSettings().dict(by_alias=True)
-
-
-def test_default_settings(api_client: TestClient, api_routes: AppRoutes, default_settings):
- response = api_client.get(api_routes.site_settings)
-
- assert response.status_code == 200
-
- assert json.loads(response.content) == default_settings
-
-
-def test_update_settings(api_client: TestClient, api_routes: AppRoutes, default_settings, admin_token):
- default_settings["language"] = "fr"
- default_settings["showRecent"] = False
-
- response = api_client.put(api_routes.site_settings, json=default_settings, headers=admin_token)
-
- assert response.status_code == 200
-
- response = api_client.get(api_routes.site_settings)
- assert json.loads(response.content) == default_settings