diff --git a/.github/workflows/dockerbuild.alpine.yml b/.github/workflows/dockerbuild.alpine.yml deleted file mode 100644 index 1dec6bfa3..000000000 --- a/.github/workflows/dockerbuild.alpine.yml +++ /dev/null @@ -1,49 +0,0 @@ -name: Docker Build Alpine - -on: - push: - branches: - - new-tests - -jobs: - build: - runs-on: ubuntu-latest - steps: - # - # Checkout - # - - name: checkout code - uses: actions/checkout@v2 - # - # Setup QEMU - # - - name: Set up QEMU - id: qemu - uses: docker/setup-qemu-action@v1 - # with: - # image: tonistiigi/binfmt:latest - # platforms: all - # - # Setup Buildx - # - - name: install buildx - id: buildx - uses: docker/setup-buildx-action@v1 - with: - install: true - # - # Login to Docker Hub - # - - name: Login to Docker Hub - uses: docker/login-action@v1 - with: - username: ${{ secrets.DOCKERHUB_USERNAME }} - password: ${{ secrets.DOCKERHUB_TOKEN }} - # - # Build - # - - name: build the image - run: | - docker build --push \ - --tag hkotel/mealie:alpine \ - --platform linux/amd64,linux/arm/v7,linux/arm64 . diff --git a/.github/workflows/pytest.yml b/.github/workflows/pytest.yml index a384ffe31..210e84fbc 100644 --- a/.github/workflows/pytest.yml +++ b/.github/workflows/pytest.yml @@ -30,15 +30,15 @@ jobs: with: virtualenvs-create: true virtualenvs-in-project: true - #---------------------------------------------- - # load cached venv if cache exists - #---------------------------------------------- - - name: Load cached venv - id: cached-poetry-dependencies - uses: actions/cache@v2 - with: - path: .venv - key: venv-${{ runner.os }}-${{ hashFiles('**/poetry.lock') }} + # #---------------------------------------------- + # # load cached venv if cache exists + # #---------------------------------------------- + # - name: Load cached venv + # id: cached-poetry-dependencies + # uses: actions/cache@v2 + # with: + # path: .venv + # key: venv-${{ runner.os }}-${{ hashFiles('**/poetry.lock') }} #---------------------------------------------- # install dependencies if cache does not exist #---------------------------------------------- diff --git a/dev/dev-notes.md b/dev/dev-notes.md index f5d3ad44f..2062d6be5 100644 --- a/dev/dev-notes.md +++ b/dev/dev-notes.md @@ -16,15 +16,7 @@ Don't forget to [join the Discord](https://discord.gg/R6QDyJgbD2)! # Todo's -Documentation -- [ ] V0.1.0 Release Notes -- [ ] Nextcloud Migration How To -- [ ] New Docker Setup with Sqlite -- [ ] Update Env Variables -- [ ] New Roadmap / Milestones - Frontend -- [x] Prep / Cook / Total Time Indicator + Editor - [ ] No Meal Today Page instead of Null - [ ] Recipe Print Page - [ ] Recipe Editor Data Validation Client Side @@ -32,12 +24,7 @@ Frontend - [ ] Advanced Search Page, draft started - [ ] Filter by Category - [ ] Filter by Tags -- [ ] Search Bar redesign - - [x] Initial - - [ ] Results redesign -- [x] Replace Backups card with something like Home Assistant -- [x] Replace import card with something like Home Assistant - - [x] Select which imports to do +- [ ] Search Bar Results Redesign Backend - [ ] Database Import @@ -46,11 +33,10 @@ Backend - [ ] Meal Plans - [x] Settings - [x] Themes -- [x] Remove Print / Debug Code +- [ ] Remove Print / Debug Code - [ ] Support how to sections and how to steps - [ ] Recipe request by category/tags - SQL - [ ] Setup Database Migrations diff --git a/dev/favicon.png b/dev/favicon.png new file mode 100644 index 000000000..0ca99249e Binary files /dev/null and b/dev/favicon.png differ diff --git a/docs/docs/changelog.md b/docs/docs/changelog.md index ad82e07cd..ab5f19dd5 100644 --- a/docs/docs/changelog.md +++ b/docs/docs/changelog.md @@ -7,16 +7,22 @@ - Fixed failed database initialization at startup - Fixed misaligned text on various cards - Fixed bug that blocked opening links in new tabs + - Fixed router link bugs - Issue #122 ### Features and Improvements + - UI Language Selection - Meal Planner - Improved Search (Fuzzy Search) - New Scheduled card support - Upload/Download backups - Dockerfile now 1/5 of the size! - - **Minor** - - Continued work on button/style unification - - Adding icons to buttons + - Migrations + - Card based redesign + - Upload from the UI + - Unified Chowdown/Nextcloud import process. + - Continued work on button/style unification + - Adding icons to buttons + - New Color Theme Picker UI ### Development - Fixed Vetur config file. Autocomplete in VSCode works! diff --git a/docs/docs/getting-started/meal-planner.md b/docs/docs/getting-started/meal-planner.md index 3e71a549e..8293aace7 100644 --- a/docs/docs/getting-started/meal-planner.md +++ b/docs/docs/getting-started/meal-planner.md @@ -1,7 +1,7 @@ # Meal Planner ## Working with Meal Plans -In Mealie you can create a mealplan based off the calendar inputs on the meal planner page. There is no limit to how long or how short a meal plan is. You may also create duplicate meal plans for the same date range. After selecting your date range, click on the card for each day and seach through recipes to find your choice. After selecting a recipe for all meals save the plan. You can also randomly generate meal plans. +In Mealie you can create a mealplan based off the calendar inputs on the meal planner page. There is no limit to how long or how short a meal plan is. You may also create duplicate meal plans for the same date range. After selecting your date range, click on the card for each day and search through recipes to find your choice. After selecting a recipe for all meals save the plan. You can also randomly generate meal plans. To edit the meal in a meal plan simply select the edit button on the card in the timeline. Similiarly, to delete a mealplan click the delete button on the card in the timeline. Currently there is no support to change the date range in a meal plan. diff --git a/docs/docs/getting-started/migration-imports.md b/docs/docs/getting-started/migration-imports.md index 7d417026b..38260f1a8 100644 --- a/docs/docs/getting-started/migration-imports.md +++ b/docs/docs/getting-started/migration-imports.md @@ -1,13 +1,13 @@ # Migration -### Chowdown +## Chowdown +To migrate recipes from a Chowdown + 1. Download the code repository as a .zip file + 2. Upload the .zip file in the Chowdown section in Mealie + 3. Select import on the newly available migration. -In the Admin page on the in the Migration section you can provide a URL for a repo hosting a [Chowdown](https://github.com/clarklab/chowdown) repository and Mealie will pull the images and recipes from the instance and automatically import them into the database. Due to the nature of the yaml format you may have mixed results but you should get an error report of the recipes that had errors and will need to be manually added. Note that you can only import the repo as a whole. You cannot import individual recipes. - -We'd like to support additional migration paths. [See open issues.](https://github.com/hay-kot/mealie/issues) - -### Nextcloud Recipes -Nextcloud recipes can be imported from either a zip file the contains the data stored in Nextcloud. The zip file can be uploaded from the frontend or placed in the data/migrations/Nextcloud directory. See the example folder structure below to ensure your recipes are able to be imported. +## Nextcloud Recipes +Nextcloud recipes can be imported from a zip file the contains the data stored in Nextcloud. The zip file can be uploaded from the frontend or placed in the data/migrations/nextcloud directory. See the example folder structure below to ensure your recipes are able to be imported. ``` nextcloud_recipes.zip @@ -21,6 +21,3 @@ nextcloud_recipes.zip └── recipe_3 └── recipe.json ``` - -**Currently Proposed Are:** -- Open Eats \ No newline at end of file diff --git a/docs/docs/roadmap.md b/docs/docs/roadmap.md index 85d079eba..f752f9bbe 100644 --- a/docs/docs/roadmap.md +++ b/docs/docs/roadmap.md @@ -38,7 +38,7 @@ Feature placement is not set in stone. This is much more of a guideline than any - [ ] Additional Backup / Import Features - [ ] Import Recipes Force/Rebase options - [x] Upload .zip file -- [ ] Improved Color Picker +- [x] Improved Color Picker - [x] Meal Plan redesign ### Backend - [ ] PostgreSQL Support diff --git a/frontend/jsconfig.json b/frontend/jsconfig.json index b2c0e02ee..e69de29bb 100644 --- a/frontend/jsconfig.json +++ b/frontend/jsconfig.json @@ -1,3 +0,0 @@ -{ - "include": ["./src/**/*"] -} diff --git a/frontend/src/App.vue b/frontend/src/App.vue index 98c56b8ca..630fa1cce 100644 --- a/frontend/src/App.vue +++ b/frontend/src/App.vue @@ -58,6 +58,7 @@ export default { mounted() { this.$store.dispatch("initTheme") this.$store.dispatch("requestRecentRecipes") + this.$store.dispatch("initLang") this.darkModeSystemCheck() this.darkModeAddEventListener() }, diff --git a/frontend/src/api/migration.js b/frontend/src/api/migration.js index 398aa9547..728a4151e 100644 --- a/frontend/src/api/migration.js +++ b/frontend/src/api/migration.js @@ -2,42 +2,27 @@ import { baseURL } from "./api-utils"; import { apiReq } from "./api-utils"; import { store } from "../store/store"; -const migrationBase = baseURL + "migration/"; +const migrationBase = baseURL + "migrations/"; const migrationURLs = { - upload: migrationBase + "upload/", - delete: (file) => `${migrationBase}${file}/delete/`, - chowdownURL: migrationBase + "chowdown/repo/", - nextcloudAvaiable: migrationBase + "nextcloud/available/", - nextcloudImport: (selection) => - `${migrationBase}nextcloud/${selection}/import/`, + // New + all: migrationBase, + delete: (folder, file) => `${migrationBase}/${folder}/${file}/delete/`, + import: (folder, file) => `${migrationBase}/${folder}/${file}/import/`, }; export default { - async migrateChowdown(repoURL) { - let postBody = { url: repoURL }; - let response = await apiReq.post(migrationURLs.chowdownURL, postBody); + async getMigrations() { + let response = await apiReq.get(migrationURLs.all); + return response.data; + }, + async delete(folder, file) { + let response = await apiReq.delete(migrationURLs.delete(folder, file)); + return response.data; + }, + async import(folder, file) { + let response = await apiReq.post(migrationURLs.import(folder, file)); store.dispatch("requestRecentRecipes"); return response.data; }, - async getNextcloudImports() { - let response = await apiReq.get(migrationURLs.nextcloudAvaiable); - return response.data; - }, - async importNextcloud(selected) { - let response = await apiReq.post(migrationURLs.nextcloudImport(selected)); - return response.data; - }, - async uploadFile(form_data) { - let response = await apiReq.post(migrationURLs.upload, form_data, { - headers: { - "Content-Type": "multipart/form-data", - }, - }); - return response.data; - }, - async delete(file_folder_name) { - let response = await apiReq.delete(migrationURLs.delete(file_folder_name)); - return response.data; - }, }; diff --git a/frontend/src/components/Recipe/RecipeEditor/index.vue b/frontend/src/components/Recipe/RecipeEditor/index.vue index 637fcd49b..74b5d27d1 100644 --- a/frontend/src/components/Recipe/RecipeEditor/index.vue +++ b/frontend/src/components/Recipe/RecipeEditor/index.vue @@ -12,26 +12,26 @@ > - - - - - - - + + + + + + + mdi-plus + diff --git a/frontend/src/components/Settings/Backup/AvailableBackupCard.vue b/frontend/src/components/Settings/Backup/AvailableBackupCard.vue index c89d6915f..67b83aa51 100644 --- a/frontend/src/components/Settings/Backup/AvailableBackupCard.vue +++ b/frontend/src/components/Settings/Backup/AvailableBackupCard.vue @@ -16,11 +16,11 @@ v-for="backup in backups" :key="backup.name" > - + - mdi-backup-restore + mdi-backup-restore
diff --git a/frontend/src/components/Settings/Backup/index.vue b/frontend/src/components/Settings/Backup/index.vue index 70c2c9edb..d16e65164 100644 --- a/frontend/src/components/Settings/Backup/index.vue +++ b/frontend/src/components/Settings/Backup/index.vue @@ -34,6 +34,8 @@ :backups="availableBackups" /> + + General Settings + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/frontend/src/components/Settings/Migration/MigrationCard.vue b/frontend/src/components/Settings/Migration/MigrationCard.vue new file mode 100644 index 000000000..139ff2dc1 --- /dev/null +++ b/frontend/src/components/Settings/Migration/MigrationCard.vue @@ -0,0 +1,97 @@ + + + + + \ No newline at end of file diff --git a/frontend/src/components/Settings/Migration/index.vue b/frontend/src/components/Settings/Migration/index.vue index 4de4e6dcf..976756298 100644 --- a/frontend/src/components/Settings/Migration/index.vue +++ b/frontend/src/components/Settings/Migration/index.vue @@ -1,44 +1,96 @@ diff --git a/frontend/src/components/Settings/Theme/ColorPickerDialog.vue b/frontend/src/components/Settings/Theme/ColorPickerDialog.vue index 6da100082..3504e9e49 100644 --- a/frontend/src/components/Settings/Theme/ColorPickerDialog.vue +++ b/frontend/src/components/Settings/Theme/ColorPickerDialog.vue @@ -1,36 +1,28 @@ @@ -44,21 +36,30 @@ export default { return { dialog: false, swatches: false, - color: "#FF00FF", + color: "#1976D2", + mask: "!#XXXXXXXX", + menu: false, }; }, - + computed: { + swatchStyle() { + const { value, menu } = this; + return { + backgroundColor: value, + cursor: "pointer", + height: "30px", + width: "30px", + borderRadius: menu ? "50%" : "4px", + transition: "border-radius 200ms ease-in-out", + }; + }, + }, watch: { color() { this.updateColor(); }, }, methods: { - toggleSwatches() { - if (this.swatches) { - this.swatches = false; - } else this.swatches = true; - }, updateColor() { this.$emit("input", this.color); }, diff --git a/frontend/src/components/UI/SuccessFailureAlert.vue b/frontend/src/components/UI/SuccessFailureAlert.vue index 784ed2e82..0f6982d63 100644 --- a/frontend/src/components/UI/SuccessFailureAlert.vue +++ b/frontend/src/components/UI/SuccessFailureAlert.vue @@ -1,32 +1,50 @@ diff --git a/frontend/src/i18n.js b/frontend/src/i18n.js index 2b285c50a..41d46703c 100644 --- a/frontend/src/i18n.js +++ b/frontend/src/i18n.js @@ -1,23 +1,27 @@ -import Vue from 'vue' -import VueI18n from 'vue-i18n' +import Vue from "vue"; +import VueI18n from "vue-i18n"; -Vue.use(VueI18n) +Vue.use(VueI18n); -function loadLocaleMessages () { - const locales = require.context('./locales', true, /[A-Za-z0-9-_,\s]+\.json$/i) - const messages = {} +function loadLocaleMessages() { + const locales = require.context( + "./locales", + true, + /[A-Za-z0-9-_,\s]+\.json$/i + ); + const messages = {}; locales.keys().forEach(key => { - const matched = key.match(/([A-Za-z0-9-_]+)\./i) + const matched = key.match(/([A-Za-z0-9-_]+)\./i); if (matched && matched.length > 1) { - const locale = matched[1] - messages[locale] = locales(key) + const locale = matched[1]; + messages[locale] = locales(key); } - }) - return messages + }); + return messages; } export default new VueI18n({ - locale: process.env.VUE_APP_I18N_LOCALE || 'en', - fallbackLocale: process.env.VUE_APP_I18N_FALLBACK_LOCALE || 'en', - messages: loadLocaleMessages() -}) + locale: "en", + fallbackLocale: process.env.VUE_APP_I18N_FALLBACK_LOCALE || "en", + messages: loadLocaleMessages(), +}); diff --git a/frontend/src/main.js b/frontend/src/main.js index 76a58cfef..a99f64d6a 100644 --- a/frontend/src/main.js +++ b/frontend/src/main.js @@ -4,7 +4,7 @@ import vuetify from "./plugins/vuetify"; import store from "./store/store"; import VueRouter from "vue-router"; import { routes } from "./routes"; -import i18n from './i18n' +import i18n from "./i18n"; Vue.config.productionTip = false; Vue.use(VueRouter); @@ -14,12 +14,13 @@ const router = new VueRouter({ mode: process.env.NODE_ENV === "production" ? "history" : "hash", }); + new Vue({ vuetify, store, router, i18n, - render: (h) => h(App) + render: h => h(App), }).$mount("#app"); // Truncate diff --git a/frontend/src/pages/SettingsPage.vue b/frontend/src/pages/SettingsPage.vue index 441029ef3..bc1d2a924 100644 --- a/frontend/src/pages/SettingsPage.vue +++ b/frontend/src/pages/SettingsPage.vue @@ -13,7 +13,8 @@ " > - + + @@ -39,6 +40,7 @@